之前一直在准备暑期实习的笔试和面试, 因此博客断更了很久…回头做6.5840发现自己的代码逻辑都快忘了…
先整理下实习求职过程中学习的C++的新特性, 由于C++11已经使用得很广泛了, 包括智能指针、各种转换运算符、lambda表达式已经成为面试常见考点了,这里我就不提这些了,因此我只梳理从C++17开始的知识点,包括C++17、C++20、C++23和少量C++26。
之前断更的6.5840的最后一个lab4B也会补上
1 auto作为函数形参
C++20 中允许在函数声明中直接使用 auto 作为参数类型,这其实是一种简化模板函数定义的语法糖。该 auto 的使用方式类似于模板函数,但语法更为简洁。
- 原始的函数模板实现
1
2
3
4template<typename T>
void f(T x) {
cout << x << endl;
} auto作为形参的实现1
2
3void f(auto x) {
cout << x << endl;
}
原理
当编译器遇到一个使用 auto 作为参数类型的函数定义时,它会将这个函数视为一个模板函数。编译器内部的处理过程如下:
模板化:编译器将
auto参数的函数自动转换为模板函数。上述void f(auto x)实际上被编译器转换为:1
2
3
4template<typename T>
void f(T x) {
cout << x << endl;
}这里的
T是由编译器自动生成的一个模板参数。类型推导:当这个函数被调用时,编译器将根据传入的实参推导出
T的具体类型。
2 <=>运算符
C++20 引入的了新的比较运算符<=>, 该运算符允许在一个表达式中执行多态的、全面的比较,并根据比较结果返回一个可传递到std::strong_ordering、std::weak_ordering或std::partial_ordering枚举类型的值, 其比较逻辑如下:。
1 | a <=> b |
比较左右两边的操作数a和b,并可能返回以下三个值之一:
std::strong_ordering:std::strong_ordering::less:如果a严格小于b。std::strong_ordering::equal:如果a等于b。std::strong_ordering::greater:如果a严格大于b。
std::weak_ordering(适用于无法提供强排序的对象,比如浮点数NaN):std::weak_ordering::lessstd::weak_ordering::equivalent(不同于等于,可能涉及NaN的比较)std::weak_ordering::greater
std::partial_ordering(用于那些只在部分情况下可以比较的对象):std::partial_ordering::lessstd::partial_ordering::equivalentstd::partial_ordering::greaterstd::partial_ordering::unordered(表示两个操作数不可比较)
简而言之, <=>使得单一的运算符具备处理所有比较的情况的能力。其重载方式也类似其他如=的运算符:
1 | class MyClass { |
3 枚举优化
3.1 支持特性的枚举
C++17 支持对枚举成员进行特性声明:
1 | enum class Color { RED, GREEN, BLUE [[deprecated]] }; |
3.2 switch中枚举的优化
C++20在switch枚举使做出了优化, 可以通过using ...的方式简化枚举类型的声明:
1 | // C++11 enum/enum class allows setting the underlying type |
4 更方便的流程控制
4.1 条件判断前的初始化
C++17允许在if和switch前进行变量的初始化(类似golang的语法):
1 | void func1() { |
4.2 指定迭代范围的for循环
C++20引入了指定范围的for循环语法, 其支持自定义的初始化列表:
1 | void func2() { |
5 安全的联合体variant
C++17 引入了一个 std::variant 提供类型安全的联合体(Type-Safe Union)。std::variant 是一个模板类,它可以存储一组预定义的不同类型的数据,但是在任何时候仅能存储其中的一种类型,类似于传统的 C 语言中的 union,但它带有现代 C++ 的类型安全保证。
std::variant 提供了多种工具来管理和访问存储的值,例如:
index()函数用于返回当前存储类型的索引。holds_alternative<SomeType>()用于检查当前存储的值是否为特定类型。get<T>()或get_if<T>()方法用于访问存储的值;若试图访问错误的类型,则get()将抛出std::bad_variant_access异常,而get_if()则返回一个指向相应类型值的指针(若不匹配则返回nullptr)。
案例代码:
1 |
|
6 避免unused warning
C++17和C++26引入了更优雅的避免unused warning的手段:
1 | void func3() { |