6. 现代C++核心特性

类型推导

1. auto关键字

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
// 基本用法
auto i = 42;              // int
auto d = 3.14;           // double
auto str = "hello";      // const char*
auto vec = std::vector<int>{1, 2, 3};  // std::vector<int>

// 与const和引用配合
const auto& val = someFunction();  // 常量引用
auto&& ref = someValue;           // 通用引用(完美转发)

// 在循环中使用
std::vector<std::pair<std::string, int>> pairs;
for (const auto& [name, value] : pairs) {  // 结构化绑定(C++17)
    std::cout << name << ": " << value << "\n";
}

2. decltype关键字

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
// 推导表达式类型
int i = 42;
decltype(i) j = i;       // int

std::vector<int> vec;
decltype(vec[0]) val = 42;  // int&

// 用于后置返回类型
template<typename T, typename U>
auto add(T t, U u) -> decltype(t + u) {
    return t + u;
}

// decltype(auto)(C++14)
decltype(auto) f() {
    int x = 0;
    return (x);  // 返回int&,因为(x)是左值表达式
}

3. 类型推导规则

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
// 模板类型推导
template<typename T>
void f(T param);

int x = 42;
const int cx = x;
const int& rx = x;

f(x);   // T 推导为 int
f(cx);  // T 推导为 int
f(rx);  // T 推导为 int

// auto类型推导
auto x1 = 27;          // int
const auto x2 = x1;    // const int
const auto& x3 = x1;   // const int&
auto&& x4 = x1;        // int&
auto&& x5 = 27;        // int&&

Lambda表达式

1. 基本语法

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
// 最简单的lambda
auto lambda1 = [] { std::cout << "Hello Lambda\n"; };
lambda1();  // 调用

// 带参数的lambda
auto lambda2 = [](int x, int y) { return x + y; };
std::cout << lambda2(3, 4) << "\n";  // 输出7

// 指定返回类型
auto lambda3 = [](int x, double y) -> double {
    return x + y;
};

2. 捕获列表

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
int multiplier = 10;
std::string prefix = "Result: ";

// 值捕获
auto lambda1 = [multiplier](int x) { return x * multiplier; };

// 引用捕获
auto lambda2 = [&prefix](int x) { prefix += std::to_string(x); };

// 混合捕获
auto lambda3 = [multiplier, &prefix](int x) {
    prefix += std::to_string(x * multiplier);
};

// 捕获this指针
class MyClass {
    int value;
public:
    auto getValueLambda() {
        return [this] { return value; };
    }
};

// 广义捕获(C++14)
auto lambda4 = [ptr = std::make_unique<int>(42)] {
    return *ptr;
};

3. 泛型Lambda(C++14)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
// 自动推导参数类型
auto lambda = [](auto x, auto y) {
    return x + y;
};

std::cout << lambda(1, 2) << "\n";      // int
std::cout << lambda(1.5, 2.3) << "\n";  // double
std::cout << lambda("Hello"s, " World"s) << "\n";  // string

// 带模板参数的lambda(C++20)
auto lambda2 = []<typename T>(std::vector<T> const& vec) {
    return vec.size();
};

移动语义

1. 右值引用

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
// 右值引用基础
int&& rref = 42;  // 右值引用
std::string&& sref = std::string("hello");  // 临时对象的右值引用

// 移动构造函数
class MyClass {
    std::string str;
public:
    MyClass(MyClass&& other) noexcept
        : str(std::move(other.str)) {}  // 移动构造
};

// 移动赋值运算符
MyClass& operator=(MyClass&& other) noexcept {
    if (this != &other) {
        str = std::move(other.str);
    }
    return *this;
}

2. 完美转发

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
// 通用引用和完美转发
template<typename T>
void wrapper(T&& arg) {
    // 完美转发参数
    foo(std::forward<T>(arg));
}

// 多参数完美转发
template<typename... Args>
void wrapper(Args&&... args) {
    foo(std::forward<Args>(args)...);
}

// 工厂函数示例
template<typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&&... args) {
    return std::unique_ptr<T>(
        new T(std::forward<Args>(args)...)
    );
}

3. 移动语义最佳实践

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Buffer {
    std::vector<char> data;
public:
    // 移动优化
    void append(std::string&& str) {
        data.insert(data.end(), 
                   str.begin(), 
                   str.end());
    }
    
    // 返回值优化
    std::vector<char> extract() {
        return std::move(data);  // 显式移动
    }
};

// 条件移动
template<typename T>
void conditionalMove(T& obj) {
    if (/* 某些条件 */) {
        other.takeOwnership(std::move(obj));
    }
}

其他现代特性

1. 范围for循环

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
std::vector<int> numbers = {1, 2, 3, 4, 5};

// 基本用法
for (const auto& num : numbers) {
    std::cout << num << " ";
}

// 自定义类型的范围for
class Range {
    int* begin_;
    int* end_;
public:
    int* begin() { return begin_; }
    int* end() { return end_; }
};

// 初始化器for循环(C++20)
for (std::vector<int> vec{1, 2, 3}; const auto& num : vec) {
    std::cout << num << " ";
}

2. 智能指针增强

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
// make_unique(C++14)
auto ptr1 = std::make_unique<int>(42);
auto ptr2 = std::make_unique<std::vector<int>>(10, 0);

// 数组支持
auto arr = std::make_unique<int[]>(10);

// shared_ptr with custom deleter
auto deleter = [](int* p) {
    std::cout << "Deleting " << *p << "\n";
    delete p;
};
std::shared_ptr<int> ptr(new int(42), deleter);

3. constexpr增强

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// constexpr函数
constexpr int fibonacci(int n) {
    if (n <= 1) return n;
    return fibonacci(n-1) + fibonacci(n-2);
}

// constexpr变量
constexpr int fib10 = fibonacci(10);

// constexpr构造函数(C++14)
class Point {
    int x_, y_;
public:
    constexpr Point(int x, int y) : x_(x), y_(y) {}
    constexpr int getX() const { return x_; }
    constexpr int getY() const { return y_; }
};

// constexpr if(C++17)
template<typename T>
auto getValue(T t) {
    if constexpr (std::is_pointer_v<T>) {
        return *t;
    } else {
        return t;
    }
}

4. 结构化绑定(C++17)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
// 数组绑定
int arr[] = {1, 2, 3};
auto [x, y, z] = arr;

// 元组绑定
std::tuple<int, std::string, double> tuple{1, "hello", 3.14};
auto [id, name, value] = tuple;

// 结构体绑定
struct Point {
    int x;
    int y;
};
Point p{1, 2};
auto [px, py] = p;

// 在循环中使用
std::map<std::string, int> scores;
for (const auto& [name, score] : scores) {
    std::cout << name << ": " << score << "\n";
}

57.12k 字
43篇文章