之前一直在准备暑期实习的笔试和面试, 因此博客断更了很久…回头做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::less
std::weak_ordering::equivalent
(不同于等于,可能涉及NaN的比较)std::weak_ordering::greater
std::partial_ordering
(用于那些只在部分情况下可以比较的对象):std::partial_ordering::less
std::partial_ordering::equivalent
std::partial_ordering::greater
std::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() { |