Bustub前置知识:C++

143 阅读3分钟

C++11新功能

  • auto关键字
  • Lambda
  • 智能指针(unique_ptr, shared_ptr, weak_ptr)
  • 右值引用
  • 元组

auto关键字

  1. 常用在循环中

    // Iterating using auto
    for (auto itr = mapOfStrs.begin(); itr != mapOfStrs.end(); ++itr)
    {
        std::cout << itr->first << "::" << itr->second << std::endl;
    }
    
  2. auto类型确定后不可变

    auto x = 1;
    // This will cause a compile-time error because 'x' is of type int
    // x = "dummy";
    
  3. 返回类型为 auto

    auto sum(int x, int y) -> int {
        return x + y;
    }
    
    // Calling the function that returns 'auto'
    auto value = sum(3, 5);
    

可变参数模板

可变参数模板是可以接受任意数量参数的模板

log函数工作原理:

  1. 它打印第一个参数。
  2. 它以递归方式调用其余参数。
#include <iostream>

// Function to end the recursion of variadic template function
void log() {
    // This can be empty or used to print something that marks the end of output.
}

template<typename T, typename... Args>
void log(T first, Args... args) 
{
    std::cout << first;
    if constexpr (sizeof...(args) > 0)
    {
        std::cout << " , ";
        log(args...);
    }
    else
    {
        std::cout << std::endl; // New line for the last element
    }
}

int main()
{
    // Calling log() functio with 3 arguments
    log(1 , 4.3 , "Hello");

    // Calling log() functio with 4 arguments
    log('a', "test", 78L, 5);

    // Calling log() functio with 2 arguments
    log("sample", "test");

    return 0;
}

delete关键字

delete 关键字可以应用于函数,使它们不可调用

下面是删除函数的简单示例:

void someFunction() = delete;

隐式类型转换可能很方便,但很危险。如果类型意外转换,它们可能会导致数据丢失或逻辑错误。删除特定的构造函数可以防止这些不需要的转换。例如:

// A constructor that might lead to implicit conversions
User(int userId, std::string userName);

// Creating an object with potentially problematic conversions
User obj4(5.5, "Riti");  // double to int
User obj5('a', "Riti");   // char to int

若要防止这些转换,请将这些构造函数声明为 deleted:

// Deleting constructors to prevent implicit conversions
User(double userId, std::string userName) = delete;
User(char userId, std::string userName) = delete;

在这里,我们将删除两个可能导致隐式转换的构造函数:

限制在堆上创建对象, 要确保仅在堆栈(而不是堆上)创建类的实例,您可以删除 new 运算符:

class User {
    // ...
    // Delete the new operator to prevent heap allocation
    void* operator new(size_t) = delete;
};

此行确保 new 运算符不能与 User 类一起使用。因此,以下代码将触发编译时错误

// Error: Use of deleted function 'static void* User::operator new(size_t)'
User* userPtr = new User(1, "Riti");

std::bind

是一种通用工具,用于通过将参数绑定到给定函数来创建新的函数对象

#include <iostream>
#include <functional> // 包含这个头文件以使用 std::bind
using namespace std;
int add(int first, int second){
    return first + second;
}

int main(){
    auto add_func = std::bind(&add, std::placeholders::_1, std::placeholders::_2);
    cout << "result:" << add_func(1, 3) << endl;
    return 0;
}

Lambda

[capture](parameters) mutable exception -> return_type {
    // function body
}

[capture]

  • []:未捕获任何内容。
  • [x, &y]x按值捕获,y按引用捕获。
  • [=]:作用域中的所有变量都按值捕获。
  • [&]:作用域中的所有变量都通过引用捕获。

三个示例

int y = 10;
auto lambda = [&y](int x) mutable {
    y = x * y; // 这是有效的,因为 y 是通过引用捕获的,并且 lambda 是 'mutable'
    std::cout << y << std::endl;
};
lambda(5); // 输出 50
#include <iostream>
#include <algorithm>

int main()
{
    int arr[] = {1, 2, 3, 4, 5};
    int discount = 50;

    // 按值捕获
    std::for_each(arr,
                  arr + sizeof(arr) / sizeof(int),
                  [=](int x) mutable {
                        std::cout << x << " ";
                        // 无法在此处修改“discount”,因为它是按值捕获的,除非使用“mutable”。
                        discount = 20;
                  });

    std::cout << std::endl;

    std::cout << "discount Vaue: " << discount << std::endl;
    return 0;
}
/* 输出:
1 2 3 4 5 
discount Vaue: 50
*/

123

asd

asd

asd