C++11及以后的版本(C++14, C++17, C++20, C++23)都增加了许多新特性。下面是每个版本的主要新特性概览:
C++11 新特性
- 自动类型推导:
auto
关键字用于自动推断变量类型。 - 范围for循环:简化遍历容器的方式。
- Lambda表达式:支持匿名函数。
- 智能指针:
std::shared_ptr
、std::unique_ptr
和std::weak_ptr
。 - 右值引用:用于优化对象的移动操作,
&&
表示右值引用。 - 移动语义:
std::move
和std::forward
用于优化对象转移。 nullptr
:用于表示空指针,替代NULL
。- 常量表达式:
constexpr
关键字用于定义常量表达式函数。 - 线程支持:
<thread>
库和相关的多线程支持。 - 静态断言:
static_assert
用于在编译时进行断言。 - 强类型枚举:
enum class
提供了强类型枚举。 - 统一的初始化语法:支持花括号
{}
初始化。 - 基于堆栈的内存分配:
std::array
和std::vector
的改进。 - 模板别名:
using
关键字用于定义模板别名。 - 变长模板:支持模板参数包。
C++14 新特性
- 泛型Lambda表达式:Lambda表达式支持模板参数。
- 返回类型推导:函数返回类型可以通过
auto
关键字推导。 - 二进制字面量:可以直接使用二进制表示法,如
0b1010
。 - 数字分隔符:用单引号
'
分隔数字,如1'000'000
。 constexpr
改进:允许更复杂的constexpr
表达式。std::make_unique
:为std::unique_ptr
提供的便捷创建方法。
C++17 新特性
- 结构化绑定:允许解构变量赋值,如
auto [a, b] = somePair;
。 - 折叠表达式:用于简化变长模板参数的表达式处理。
std::optional
:用于表示可空值。std::variant
:支持类型安全的联合体。std::any
:可以保存任意类型的值。if
和switch
语句中的初始化:允许在条件语句中进行变量初始化。std::string_view
:提供更高效的字符串视图。constexpr if
:编译时条件判断。- 文件系统库:
<filesystem>
提供文件系统操作支持。
C++20 新特性
- 协程:支持协程的关键字
co_await
,co_yield
, 和co_return
。 - 模块:引入模块系统,替代传统头文件。
- 概念:使用
concept
关键字定义模板的约束。 - 范围库:提供更方便的操作范围的库,如
std::ranges
。 - 三向比较运算符:支持
<=>
三向比较。 consteval
和constinit
:改进编译时常量表达式处理。- 增强的Lambda捕获:Lambda表达式支持更灵活的捕获列表。
std::span
:提供对数组和容器的视图。- 日历和时区库:标准库增加了日期和时间处理库。
- 移除过时特性:如
std::auto_ptr
,register
关键字等被移除。
C++23 新特性
- 静态警告:
static_warning
用于编译时警告。 - 更多的
constexpr
支持:更多标准库函数和算法支持constexpr
。 - 改进的多线程支持:包括新的同步原语和线程管理功能。
- 扩展的范围库:进一步增强和扩展范围库的功能。
- 标准库的并行算法:增强并行和并发处理能力。
- 改进的错误处理:更强大的异常处理机制和诊断信息。
下面将分别为每个概念提供一个简单的示例代码,以便更好地理解这些特性。
C++11 新特性
-
自动类型推导
auto x = 10; // x 被推导为 int 类型
-
范围for循环
std::vector<int> vec = {1, 2, 3, 4}; for (auto& v : vec) { std::cout << v << " "; }
-
Lambda表达式
auto add = [](int a, int b) { return a + b; }; std::cout << add(2, 3);
-
智能指针
std::shared_ptr<int> p1 = std::make_shared<int>(10); std::unique_ptr<int> p2 = std::make_unique<int>(20);
-
右值引用
void foo(int&& x) { std::cout << x; } foo(10); // 10 是右值
-
移动语义
std::vector<int> vec1 = {1, 2, 3}; std::vector<int> vec2 = std::move(vec1); // vec1 资源被转移到 vec2
-
nullptr
int* p = nullptr; // p 是空指针
-
常量表达式
constexpr int square(int x) { return x * x; } int result = square(5); // 在编译时计算
-
线程支持
#include <thread> void hello() { std::cout << "Hello, world!"; } std::thread t(hello); t.join(); // 等待线程结束
-
静态断言
static_assert(sizeof(int) == 4, "int size is not 4 bytes");
-
强类型枚举
enum class Color { Red, Green, Blue }; Color c = Color::Red;
-
统一的初始化语法
int arr[] = {1, 2, 3}; std::vector<int> vec = {1, 2, 3};
-
基于堆栈的内存分配
std::array<int, 3> arr = {1, 2, 3};
-
模板别名
template <typename T> using Vec = std::vector<T>; Vec<int> vec = {1, 2, 3};
-
变长模板
template<typename... Args> void print(Args... args) { (std::cout << ... << args) << '\n'; } print(1, 2, 3); // 输出:123
C++14 新特性
-
泛型Lambda表达式
auto lambda = [](auto x, auto y) { return x + y; }; std::cout << lambda(1, 2); // 输出 3
-
返回类型推导
auto add(int a, int b) { return a + b; }
-
二进制字面量
int bin = 0b1010; // bin 为 10
-
数字分隔符
int million = 1'000'000; // 方便读写
-
constexpr
改进constexpr int factorial(int n) { return n <= 1 ? 1 : (n * factorial(n - 1)); }
-
std::make_unique
auto p = std::make_unique<int>(10);
C++17 新特性
-
结构化绑定
std::tuple<int, double, std::string> t(1, 2.3, "hello"); auto [i, d, s] = t; // i = 1, d = 2.3, s = "hello"
-
折叠表达式
template<typename... Args> auto sum(Args... args) { return (args + ...); // 将所有参数相加 } std::cout << sum(1, 2, 3); // 输出 6
-
std::optional
std::optional<int> opt; if (!opt) { opt = 42; } std::cout << *opt; // 输出 42
-
std::variant
std::variant<int, std::string> v = "hello"; std::cout << std::get<std::string>(v); // 输出 hello
-
std::any
std::any a = 10; a = std::string("hello"); std::cout << std::any_cast<std::string>(a); // 输出 hello
-
if
和switch
语句中的初始化if (std::vector<int> v = {1, 2, 3}; !v.empty()) { std::cout << v.size(); // 输出 3 }
-
std::string_view
std::string_view sv = "hello"; std::cout << sv; // 输出 hello
-
constexpr if
template<typename T> void foo(T t) { if constexpr (std::is_integral_v<T>) { std::cout << "Integral type"; } else { std::cout << "Non-integral type"; } }
-
文件系统库
#include <filesystem> namespace fs = std::filesystem; for (auto& p : fs::directory_iterator("/path/to/dir")) { std::cout << p.path() << '\n'; }
C++20 新特性
-
协程
#include <coroutine> struct task { struct promise_type { task get_return_object() { return {}; } std::suspend_never initial_suspend() { return {}; } std::suspend_never final_suspend() noexcept { return {}; } void return_void() {} void unhandled_exception() {} }; }; task foo() { co_return; }
-
模块
// 文件: my_module.cpp export module my_module; export void my_function() { std::cout << "Hello, modules!"; } // 文件: main.cpp import my_module; int main() { my_function(); // 输出 Hello, modules! return 0; }
-
概念
template<typename T> concept Integral = std::is_integral_v<T>; template<Integral T> T add(T a, T b) { return a + b; }
-
范围库
#include <ranges> std::vector<int> vec = {1, 2, 3, 4}; auto even = vec | std::views::filter([](int i) { return i % 2 == 0; }); for (int i : even) { std::cout << i << " "; // 输出 2 4 }
-
三向比较运算符
std::partial_ordering cmp = 1.0 <=> 2.0; if (cmp == std::partial_ordering::less) { std::cout << "1.0 is less than 2.0"; }
-
consteval
和constinit
consteval int square(int n) { return n * n; } constinit int x = square(5); // x 在编译时计算
-
增强的Lambda捕获
int x = 10; auto lambda = [y = x + 1] { return y; }; std::cout << lambda(); // 输出 11
-
std::span
void print_span(std::span<int> s) { for (int i : s) { std::cout << i << " "; } } int arr[] = {1, 2, 3, 4}; print_span(arr); // 输出 1 2 3 4
-
日历和时区库
#include <chrono> using namespace std::chrono; auto now = system_clock::now(); auto today = floor<days>(now); std::cout << today.time_since_epoch().count();
-
移除过时特性
// 旧代码: // std::auto_ptr<int> p(new int(10)); // 被移除 // 新代码: std::unique_ptr<int> p = std::make_unique<int>(10);
C++23 新特性
-
静态警告
#ifdef __cpp_static_assert static_warning(sizeof(int) == 4, "int size is not 4 bytes"); #endif
-
更多的
constexpr
支持constexpr int gcd(int a, int b) { return b == 0 ? a : gcd(b, a % b); } static_assert(gcd(10, 5) == 5, "GCD calculation failed");
-
改进的多线程支持
#include <barrier> std::barrier sync_point(2); std::thread t1([&]() { // Do work sync_point.arrive_and_wait(); }); std::thread t2([&]() { // Do work sync_point.arrive_and_wait(); }); t1.join(); t2.join();
-
扩展的范围库
#include <ranges> std::vector<int> vec = {1, 2, 3, 4, 5, 6}; auto result = vec | std::views::take(4) | std::views::reverse; for (int i : result) { std::cout << i << " "; // 输出 4 3 2 1 }
-
标准库的并行算法
#include <algorithm> #include <execution> std::vector<int> vec = {3, 1, 4, 1, 5, 9, 2, 6, 5}; std::sort(std::execution::par, vec.begin(), vec.end()); for (int i : vec) { std::cout << i << " "; // 输出 1 1 2 3 4 5 5 6 9 }
-
改进的错误处理
#include <expected> std::expected<int, std::string> divide(int a, int b) { if (b == 0) return std::unexpected("Division by zero"); return a / b; } auto result = divide(10, 2); if (result) { std::cout << *result; // 输出 5 } else { std::cout << result.error(); }