C++: C++17/20 新特性
最后更新:2026-08-26
第47课我们学了模板元编程。
现在,我们要学习C++17和C++20的新特性。
这些新特性让C++更简洁、更安全、更强大。
1. C++17新特性
(1) 1.1 结构化绑定(Structured Binding)
功能: 方便地从tuple、pair、结构体中解包。
示例:结构化绑定(难度⭐)
▶ 示例 2:代码示例(难度⭐)
CPP
#include <iostream>
#include <tuple>
int main() {
std::tuple<int, std::string, double> t = {1, "Hello", 3.14};
// C++17:结构化绑定
auto [id, name, score] = t;
std::cout << "ID: " << id << std::endl;
std::cout << "Name: " << name << std::endl;
std::cout << "Score: " << score << std::endl;
return 0;
}
输出:
TEXT
📖 仅展示
ID: 1
Name: Hello
Score: 3.14
(2) 1.2 if constexpr
功能: 编译期if,根据条件选择性编译代码。
示例:if constexpr(难度⭐⭐)
CPP
#include <iostream>
#include <type_traits>
template<typename T>
auto process(T value) {
if constexpr (std::is_integral_v<T>) {
return value * 2; // 整数:翻倍
} else {
return value; // 其他:原样返回
}
}
int main() {
std::cout << process(10) << std::endl; // 20
std::cout << process(3.14) << std::endl; // 3.14
return 0;
}
(3) 1.3 折叠表达式
功能: 简化可变参数模板。
示例:折叠表达式(难度⭐⭐)
CPP
#include <iostream>
template<typename... Args>
void print(Args... args) {
(std::cout << ... << args) << std::endl; // 折叠表达式
}
int main() {
print(1, 2, 3, 4, 5); // 输出:12345
return 0;
}
(4) 1.4 其他C++17特性
| 特性 | 说明 |
|---|---|
std::optional |
可能为空的值 |
std::variant |
类型安全的union |
std::any |
任意类型 |
std::string_view |
字符串视图(零拷贝) |
| 类模板参数推导 | 不必写 pair<int, int> 了 |
2. C++20新特性
(1) 2.1 概念(Concepts)
功能: 约束模板参数,让错误信息更友好。
示例:用概念约束模板(难度⭐⭐⭐)
CPP
#include <iostream>
#include <concepts>
// 约束T必须是整数类型
template<typename T>
requires std::integral<T>
T doubleValue(T x) {
return x * 2;
}
int main() {
std::cout << doubleValue(10) << std::endl; // 20
// std::cout << doubleValue(3.14) << std::endl; // ❌ 编译错误(清晰)
return 0;
}
(2) 2.2 范围库(Ranges)
功能: 更简洁的STL算法调用方式。
示例:用ranges(难度⭐⭐)
CPP
#include <iostream>
#include <ranges>
#include <vector>
int main() {
std::vector<int> v = {1, 2, 3, 4, 5};
// C++20:ranges
auto result = v | std::views::filter([](int x) { return x % 2 == 0; })
| std::views::transform([](int x) { return x * 10; });
for (int x : result) {
std::cout << x << " "; // 输出:20 40
}
std::cout << std::endl;
return 0;
}
(3) 2.3 协程(Coroutines)
功能: 支持协程(暂停/恢复的函数)。
示例:简单协程(难度⭐⭐⭐⭐)
CPP
#include <iostream>
#include <coroutine>
// 协程需要在C++20中较复杂,这里省略具体实现
// 概念:协程可以暂停执行,稍后恢复
int main() {
// C++20协程示例(简化)
std::cout << "C++20 Coroutines" << std::endl;
return 0;
}
(4) 2.4 其他C++20特性
| 特性 | 说明 |
|---|---|
| 模块(Modules) | 替代头文件,编译更快 |
| 协程(Coroutines) | 异步编程 |
| 日期库(chrono扩展) | 更好的日期时间处理 |
| 格式化库(format) | 类似Python的format |
| 太空船运算符(<=>) | 三路比较 |
3. 新特性选择建议
(1) 3.1 应该用哪个标准?
| 标准 | 建议 |
|---|---|
| C++11 | 最低标准,必须用 |
| C++14 | 小幅改进,建议用 |
| C++17 | 很多实用特性,推荐用 |
| C++20 | 最新特性,谨慎用(编译器支持可能不完整) |
4. 实战:用C++17重构代码
▶ 示例 1:用结构化绑定简化代码(难度⭐⭐)
CPP
#include <iostream>
#include <map>
#include <string>
int main() {
std::map<int, std::string> students = {{1, "张三"}, {2, "李四"}};
// C++17:结构化绑定遍历map
for (const auto& [id, name] : students) {
std::cout << id << ": " << name << std::endl;
}
return 0;
}
输出:
TEXT
📖 仅展示
1: 张三
2: 李四
▶ 示例 3:auto 类型推导(难度⭐)
CPP
#include <iostream>
#include <vector>
int main() {
auto x = 10; // int
auto y = 3.14; // double
auto name = "Hello"; // const char*
std::vector<int> nums = {1, 2, 3, 4, 5};
auto it = nums.begin(); // vector<int>::iterator
std::cout << "x = " << x << std::endl;
std::cout << "y = " << y << std::endl;
std::cout << "name = " << name << std::endl;
return 0;
}
输出:
TEXT
📖 仅展示
x = 10
y = 3.14
name = Hello
预期输出:
TEXT
📖 仅展示
x = 10
y = 3.14
name = Hello
❓ 常见问题
Q 应该用最新标准吗?
A 不一定。考虑: - 编译器支持 - 团队熟悉度 - 项目需求
Q 怎么启用C++17/20?
A 编译时加标志:
bash g++ -std=c++17 main.cpp g++ -std=c++20 main.cpp Q C++23有什么新特性?
A - 模块化标准库 - 网络库 - 更多Ranges算法
📖 小节
| 标准 | 重要特性 |
|---|---|
| C++17 | 结构化绑定、if constexpr、折叠表达式 |
| C++20 | 概念、Ranges、协程、模块 |
📝 作业
-
**基础题 (Difficulty ⭐):分别用 auto、范围 for、nullptr 改写一个老式 C++ 代码片段(有显式类型、传统 for、NULL)。
-
**进阶题 (Difficulty ⭐⭐):用结构化绑定(C++17)解包一个 pair 或 tuple 的返回值,对比传统 .first/.second 方式。
-
**挑战题 (Difficulty ⭐⭐⭐):用 if constexpr(C++17)实现编译期分支,编写一个函数模板,对整数类型和浮点类型采用不同处理逻辑。
- C++11:auto/nullptr/范围for/lambda/智能指针
- C++14:泛型lambda/make_unique
- C++17:结构化绑定/if constexpr/string_view/文件系统
- C++20:模块/协程/概念/Ranges
- 本课程采用 C++17,平衡新特性和兼容性
下一课:性能优化(#49)