C++ 进阶(31):C++17/20/23 新特性总结——实用新特性一览
更新时间:2026-09-01。本文是
languages/cpp/intermediate/进阶第 31 篇,接 自定义分配器。C++ 每三年出一个新标准,理解新特性不是为了赶时髦,而是为了写出更简洁、安全、高效的代码。
本文要回答的问题
- C++17 最实用的新特性是什么?
- C++20 最实用的新特性是什么?
- 什么时候用新特性?什么时候不用?
一、C++17 实用新特性
1. 结构化绑定
cpp
// 返回 pair 或 tuple 时,直接解构
auto [name, age] = get_person(); // 返回 pair<string, int>
// 遍历 map
for (const auto& [key, value] : my_map) {
std::cout << key << ": " << value << "\n";
}2. if constexpr
cpp
template<typename T>
auto length(const T& v) {
if constexpr (std::is_integral_v<T>) {
// T 是整数类型,编译期选择
return v;
} else {
// T 是容器类型
return v.size();
}
}3. 折叠表达式
cpp
// 变参模板求和
template<typename... Args>
auto sum(Args... args) {
return (args + ...); // 左折叠
}
// 检查所有参数是否都满足条件
template<typename... Args>
bool all_true(Args... args) {
return (args && ...); // 逻辑与折叠
}4. 内联变量
cpp
// 头文件中定义全局变量,不需要在 cpp 中再定义
inline int global_config = 42;5. string_view
cpp
// 不拥有所有权的字符串视图
void process(std::string_view sv);二、C++20 实用新特性
1. 概念(Concepts)
cpp
template<typename T>
concept Hashable = requires(T a) {
{ std::hash<T>{}(a) } -> std::convertible_to<std::size_t>;
};
template<Hashable T>
void process(const T& v) {
// 编译期检查 T 满足 Hashable
}2. 范围库(Ranges)
cpp
// 管道操作符组合算法
auto result = v
| std::views::filter([](int x) { return x % 2 == 0; })
| std::views::transform([](int x) { return x * x; });3. 协程(Coroutines)
cpp
Generator<int> range(int n) {
for (int i = 0; i < n; i++) {
co_yield i;
}
}4. 三路比较运算符(<=>)
cpp
struct Point {
int x, y;
auto operator<=>(const Point&) const = default; // 自动生成所有比较运算符
};5. constexpr 大扩展
cpp
// C++20 中,vector 和 string 可以在 constexpr 中使用
constexpr int process() {
std::vector<int> v = {1, 2, 3};
v.push_back(4);
return v.size();
}
static_assert(process() == 4);三、C++23 实用新特性
1. std::expected
cpp
// 类似 Rust 的 Result,返回结果或错误
std::expected<int, std::string> divide(int a, int b) {
if (b == 0) {
return std::unexpected("division by zero");
}
return a / b;
}2. std::print
cpp
std::print("Hello, {}!\n", "world"); // 直接输出,比 cout 简洁
std::println("Pi = {}", 3.14);3. std::optional 的 and_then / transform
cpp
auto result = opt
.and_then([](int x) -> std::optional<int> {
return x > 0 ? std::optional{x * 2} : std::nullopt;
})
.transform([](int x) { return x + 1; });四、什么时候用新特性?
| 原则 | 说明 |
|---|---|
| 项目标准 | 项目如果还是 C++14,不能用 C++20 特性 |
| 编译器支持 | 检查编译器是否支持,GCC/Clang/MSVC 支持度不同 |
| 团队熟悉度 | 新特性如果团队不熟悉,引入成本高 |
| 代码可读性 | 新特性如果让代码更可读就用,如果更晦涩就不必 |
经验: 结构化绑定、if constexpr、string_view、fold expressions 几乎总能提升代码质量,优先用。
五、常见坑对照
| 坑 | 现象 | 对策 |
|---|---|---|
| 编译器不支持 C++20 | 编译报错 | 检查编译器版本,升级 |
| 用 C++20 特性写 C++17 项目 | 编译不过 | 检查项目标准 |
| 协程太复杂,滥用 | 代码难读难维护 | 协程只在异步场景用 |
| 模块支持不成熟 | 不同编译器模块格式不兼容 | 等编译器和工具链成熟再用 |
相关与延伸
进阶层 31 篇完成,接下来看专家层。下一篇:C++20 模块深入——模块系统、ABI 影响、编译性能。
一句话总结
C++17/20/23 新特性:C++17 最实用的是结构化绑定、if constexpr、折叠表达式、string_view;C++20 最实用的是 concepts、ranges、协程、三路比较运算符、constexpr 大扩展;C++23 最实用的是 std::expected、std::print、optional 的 and_then/transform;用新特性看项目标准、编译器支持、团队熟悉度;结构化绑定和 if constexpr 几乎总能提升代码质量。