c++14新特性
1. 函数返回值类型推导
C++14新增函数返回值也可以使用auto自动推导了。
1 | // 普通函数 |
但是注意下面特殊场景:
函数内如果有多个return语句,它们必须返回相同的类型,否则编译失败。
1
2
3
4
5auto func(bool flag) {
if (flag) return 1;
else return 2.3; // error
}
// inconsistent deduction for auto return type: ‘int’ and then ‘double’如果return语句返回初始化列表,返回值类型推导也会失败。
1
2
3auto func() {
return {1, 2, 3}; // error returning initializer list
}如果函数是虚函数,不能使用返回值类型推导。
1
2
3
4struct A {
// error: virtual function cannot have deduced return type
virtual auto func() { return 1; }
}返回类型推导可以用在前置声明中,但是在使用它们之前,翻译单元中必须能够得到函数定义。
1
2
3
4
5
6auto f(); // declared, not yet defined
auto f() { return 42; } // defined, return type is int
int main() {
cout << f() << endl;
}返回类型推导可以用在递归函数中,但是递归调用必须以至少一个返回语句作为先导,以便编译器推导出返回类型。
1
2
3
4
5
6auto sum(int i) {
if (i == 1)
return i; // return int
else
return sum(i - 1) + i; // ok
}
2. lambda匿名函数参数使用auto
在C++11中,lambda表达式参数需要使用具体的类型声明。
1 | auto f = [] (int a) { return a; } |
在C++14中,对此进行优化,lambda表达式参数可以直接是auto。
1 | auto f = [] (auto a) { return a; }; |
3. 变量模板
C++14之前,模板有函数模板和类模板,C++14新增了变量模板。本质是用变量模板的默认值在实例化时进行强转,如果成功则成功,否则报错。
1 |
|
4. 别名模板
C++14支持别名模板。
1 | template<typename T, typename U> |
5. 减少constexpr的限制
- C++11中constexpr修饰的函数,函数体不可以使用局部变量,而C++14后可以。
1 | constexpr int factorial(int n) { // C++11中不可,C++14中可以 |
- C++11中constexpr修饰的函数只能有一个return语句,而C++14可以有多个。
1 | constexpr int func(bool flag) { // C++11中不可,C++14中可以 |
6. 增加[[deprecated]]标记
C++14中增加了deprecated标记,修饰类、变量、函数等,编译时会产生警告,提示开发者该标记修饰的内容将来可能会被丢弃,尽量不要使用。
1 | struct [[deprecated]] A { }; |
当编译时,会出现如下警告:
1 | ~/test$ g++ test.cc -std=c++14 |
注:在vs2022上测试编译会报错,不是警告!
7. 二进制字面量与整形字面量分隔符
C++14引入了二进制字面量,也引入了分隔符。(防止看起来眼花)
1 |
|
8. std::make_unique
C++11中有std::make_shared,却没有std::make_unique,在C++14已经加入了。
1 | struct A {}; |
9. std::shared_timed_mutex与std::shared_lock
C++14通过std::shared_timed_mutex和std::shared_lock来实现读写锁,保证多个线程可以同时读,但是写线程必须独立运行,写操作不可以同时和读操作一起进行。
1 | struct ThreadSafe { |
shared_timed_mutex这个比用shared_mutex多了超时时间设置。
10. std::integer_sequence
是一个模板类,可以在编译期生成整数序列。
1 |
|
11. std::exchange
交换两个对象的值,T old_value = std::exchange(obj, new_value); 就是用new_value初始化obj,然后返回obj的旧值赋值给old_value。
1 | int a = 1; |
注意它与std::swap的区别,这个内部实现用的右值移动语义,避免了临时对象和拷贝操作。常使用的场景包括:
- 交换智能指针,实现原子指针交换
- 交换互斥锁的状态
- 替换容器中的元素
- 交换线程状态
12. std::quoted
C++14添加的一个字符串转义的工具类,避免手动添加转义字符的麻烦。
1 | std::string s1 = std::quoted("Hello \"World\""); |