C++11/14/17/20 新特性概览

引言

C++ 是一门不断发展的编程语言,自 C++11 以来,标准委员会不断引入新特性,以提高代码的可读性、安全性和性能。本教程将概览 C++11、C++14、C++17 和 C++20 中的主要新特性,帮助你更好地理解和应用这些新特性。

C++11 新特性

1. 自动类型推导 (auto 和 decltype)

C++11 引入了 auto 关键字,用于自动推导变量的类型。decltype 则用于推导表达式的类型。

#include <iostream>

int main() {
    auto i = 42;  // i 的类型被推导为 int
    decltype(i) j = 43;  // j 的类型与 i 相同,即 int
    std::cout << "i: " << i << ", j: " << j << std::endl;
    return 0;
}

2. 范围 for 循环

范围 for 循环使得遍历容器更加简洁。

#include <iostream>
#include <vector>

int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};
    for (auto& elem : vec) {
        std::cout << elem << " ";
    }
    return 0;
}

3. 初始化列表

C++11 引入了统一的初始化语法,可以使用大括号 {} 进行初始化。

#include <iostream>
#include <vector>

int main() {
    int arr[] = {1, 2, 3, 4, 5};
    std::vector<int> vec = {1, 2, 3, 4, 5};
    std::cout << "Array: ";
    for (int i : arr) {
        std::cout << i << " ";
    }
    std::cout << "\nVector: ";
    for (int i : vec) {
        std::cout << i << " ";
    }
    return 0;
}

4. 智能指针 (unique_ptr, shared_ptr, weak_ptr)

智能指针帮助管理动态内存,避免内存泄漏。

#include <iostream>
#include <memory>

int main() {
    std::unique_ptr<int> uptr(new int(42));
    std::shared_ptr<int> sptr = std::make_shared<int>(43);
    std::weak_ptr<int> wptr = sptr;

    std::cout << "*uptr: " << *uptr << std::endl;
    std::cout << "*sptr: " << *sptr << std::endl;
    return 0;
}

5. Lambda 表达式

Lambda 表达式允许在代码中内联定义匿名函数。

#include <iostream>
#include <vector>
#include <algorithm>

int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};
    std::for_each(vec.begin(), vec.end(), [](int& n){ n *= 2; });
    for (int i : vec) {
        std::cout << i << " ";
    }
    return 0;
}

C++14 新特性

1. 泛型 Lambda

C++14 允许在 Lambda 表达式中使用 auto 作为参数类型。

#include <iostream>
#include <vector>

int main() {
    auto lambda = [](auto x, auto y) { return x + y; };
    std::cout << lambda(1, 2) << std::endl;
    std::cout << lambda(1.5, 2.5) << std::endl;
    return 0;
}

2. 二进制字面量

C++14 引入了二进制字面量,使用 0b 或 0B 前缀。

#include <iostream>

int main() {
    int a = 0b1010;  // 二进制表示的 10
    std::cout << "a: " << a << std::endl;
    return 0;
}

C++17 新特性

1. 结构化绑定

结构化绑定允许将多个变量绑定到元组或结构体中。

#include <iostream>
#include <tuple>

int main() {
    std::tuple<int, double, std::string> t(42, 3.14, "Hello");
    auto [i, d, s] = t;
    std::cout << "i: " << i << ", d: " << d << ", s: " << s << std::endl;
    return 0;
}

2. if 和 switch 的初始化语句

C++17 允许在 if 和 switch 语句中使用初始化语句。

#include <iostream>

int main() {
    if (int x = 42; x > 0) {
        std::cout << "x is positive" << std::endl;
    }
    return 0;
}

C++20 新特性

1. 概念 (Concepts)

概念用于约束模板参数,提高代码的可读性和安全性。

#include <iostream>
#include <concepts>

template<typename T>
requires std::integral<T>
T add(T a, T b) {
    return a + b;
}

int main() {
    std::cout << add(1, 2) << std::endl;
    // std::cout << add(1.5, 2.5) << std::endl;  // 编译错误
    return 0;
}

2. 三路比较运算符 (<=>)

三路比较运算符简化了比较操作。

#include <iostream>

int main() {
    int a = 42, b = 43;
    auto result = a <=> b;
    if (result < 0) {
        std::cout << "a is less than b" << std::endl;
    } else if (result > 0) {
        std::cout << "a is greater than b" << std::endl;
    } else {
        std::cout << "a is equal to b" << std::endl;
    }
    return 0;
}

实践练习

练习 1: 使用 auto 和 decltype

编写一个程序,使用 auto 和 decltype 推导变量类型,并输出结果。

练习 2: 实现一个简单的 Lambda 表达式

编写一个程序,使用 Lambda 表达式对数组中的每个元素进行平方操作,并输出结果。

练习 3: 使用结构化绑定

编写一个程序,使用结构化绑定从 std::tuple 中提取多个变量,并输出结果。

练习 4: 使用三路比较运算符

编写一个程序,使用三路比较运算符比较两个整数,并输出比较结果。

总结

C++11/14/17/20 引入了许多新特性,极大地增强了语言的功能和表达能力。通过学习和实践这些新特性,你可以编写出更加简洁、高效和安全的 C++ 代码。希望本教程能帮助你更好地理解和应用这些新特性。