c++17/20新特性
C++17 和 C++20 新特性
C++17 新特性
C++17(2017 年发布)引入了许多实用功能,改进语言的表达力和标准库的可用性。
语言特性
结构化绑定(Structured Bindings)
- 允许解构 tuple、pair 或结构体到多个变量。
- 示例:
1
2std::pair<int, std::string> p{1, "hello"};
auto [id, value] = p; // id=1, value="hello" - 用途:简化多返回值处理。
if 和 switch 初始化语句
- 在 if/switch 中初始化变量,限制作用域。
- 示例:
1
2
3if (auto it = map.find(key); it != map.end()) {
return it->second;
} - 用途:代码更紧凑,减少作用域污染。
内联变量(Inline Variables)
- 允许在头文件中定义内联静态变量。
- 示例:
1
inline static int counter = 0; // 多翻译单元共享
- 用途:简化全局常量或静态变量定义。
折叠表达式(Fold Expressions)
- 简化变参模板的递归处理。
- 示例:
1
2template<typename... Args>
auto sum(Args... args) { return (args + ...); } - 用途:优雅处理可变参数模板。
constexpr if
- 编译期条件分支。
- 示例:
1
2
3
4
5template<typename T>
auto get_value(T t) {
if constexpr (std::is_integral_v<T>) return t * 2;
else return t;
} - 用途:优化模板代码,减少分支开销。
类模板参数推导(CTAD)
- 自动推导类模板参数。
- 示例:
1
std::pair p{1, 2.0}; // 推导为 std::pair<int, double>
- 用途:简化模板类实例化。
标准库
std::optional
- 表示可能为空的值。
- 示例:
1
2std::optional<int> opt = 42;
if (opt) std::cout << *opt; // 42 - 用途:安全处理可能不存在的值。
std::variant
- 类型安全的联合体。
- 示例:
1
2std::variant<int, std::string> v = "hello";
std::visit([](auto&& x) { std::cout << x; }, v); - 用途:替代 union,类型安全。
std::any
- 存储任意类型的值。
- 示例:
1
2std::any a = 42;
int x = std::any_cast<int>(a); - 用途:动态类型场景。
std::filesystem
- 文件系统操作库。
- 示例:
1
2std::filesystem::path p = "file.txt";
if (std::filesystem::exists(p)) { /* ... */ } - 用途:跨平台文件操作。
并行算法
- 标准算法支持并行执行。
- 示例:
1
2std::vector<int> v(1000);
std::sort(std::execution::par, v.begin(), v.end()); - 用途:利用多核提升性能。
C++20 新特性
C++20(2020 年发布)是 C++ 的一次重大更新,引入了模块、概念、协程等变革性特性。
语言特性
模块(Modules)
- 替代头文件,改进编译速度和封装。
- 示例:
1
2
3
4
5export module math;
export int add(int a, int b) { return a + b; }
// 使用
import math;
int main() { return add(1, 2); } - 用途:减少头文件依赖,加速编译。
概念(Concepts)
- 约束模板参数,增强类型检查。
- 示例:
1
2
3
4template<typename T>
concept Integral = std::is_integral_v<T>;
template<Integral T>
T square(T x) { return x * x; } - 用途:提高模板代码可读性和错误提示。
Lambda 增强
- 支持无状态 lambda 在 constexpr、显式模板参数。
- 示例:
1
2auto id = []<typename T>(T x) { return x; };
constexpr int x = []{ return 42; }(); - 用途:更灵活的 lambda 应用。
Ranges 库
- 提供范围视图和管道操作。
- 示例:
1
2
3std::vector<int> v{1, 2, 3, 4};
auto even = v | std::views::filter([](int x) { return x % 2 == 0; });
for (int x : even) std::cout << x; // 2 4 - 用途:函数式编程风格,简化迭代。
协程(Coroutines)
- 支持暂停和恢复函数执行。
- 示例:
1
2
3generator<int> count(int n) {
for (int i = 0; i < n; ++i) co_yield i;
} - 用途:异步编程、生成器。
consteval 和 constinit
consteval
:强制编译期执行。constinit
:确保静态变量初始化。- 示例:
1
2consteval int square(int x) { return x * x; }
constinit int global = 42; - 用途:优化编译期计算,控制初始化。
三路比较(Spaceship Operator)
operator<=>
自动生成比较运算符。- 示例:
1
2
3struct Point { int x, y;
auto operator<=>(const Point&) const = default;
}; - 用途:简化比较逻辑。
标准库
std::span
- 轻量视图,表示连续内存视图。
- 示例:
1
2
3void print(std::span<int> s) {
for (int x : s) std::cout << x;
} - 用途:安全访问连续数据。
std::bit_cast
- 类型安全的字节级转换。
- 示例:
1
2float f = 3.14f;
uint32_t u = std::bit_cast<uint32_t>(f); - 用途:低级数据转换。
std::format
- 格式化字符串库。
- 示例:
1
std::string s = std::format("Hello, {}!", "world");
- 用途:更安全、现代化的字符串格式化。
std::source_location
- 获取调用位置信息。
- 示例:
1
2
3void log(std::source_location loc = std::source_location::current()) {
std::cout << loc.file_name() << ":" << loc.line();
} - 用途:日志记录。
日历和时区(Calendar/Timezone)
- 支持日期时间操作。
- 示例:
1
2
3using namespace std::chrono;
auto now = std::chrono::system_clock::now();
auto date = std::year_month_day{std::floor<std::chrono::days>(now)}; - 用途:跨平台处理时间。
比较与选择
- C++17:实用性强,适合过渡项目,特性如结构化绑定、
std::optional
立即提升代码质量。 - C++20:更现代化,模块、概念、协程适合新项目,但编译器支持(如 GCC 10+、Clang 10+)和生态成熟度需考虑。
All articles on this blog are licensed under CC BY-NC-SA 4.0 unless otherwise stated.
Comments