c++14新特性
1、函数返回值类型推导
c++14对函数返回类型推导规则做了优化:
auto func(int i) { //C++11编译非法,c++14支持auto返回值类型推导 return i; } int main() { cout << func(4) << endl; return 0; }
支持函数模块返回值类型推导:
template<typename T> auto func(T t) { return t; } int main() { cout << func(4) << endl; cout << func(3.4) << endl; return 0; }
auto返回值用例:
// 编译失败,多个return语句必须返回相同类型。 auto func(bool flag) { if (flag) return 1; else return 2.3; } // 编译失败,不能返回初始化列表 auto func1() { return {1, 2, 3}; } //虚函数不能返回类型推导 class A{ virtual auto func() { return 1; } }; //返回值类型推导可以提前前声明,但使用前必须进行函数定义。 auto f(); // declared, not yet defined auto f() { return 42; } // defined, return type is int // 回类型推导可以用在递归函数中,但是递归调用必须以至少一个返回语句作为先导,以便编译器推导出返回类型。 auto sum(int i) { if (i == 1) return i; // return int else return sum(i - 1) + i; // ok } int main() { cout << f() << endl; return 0; }
2、lambda参数auto
在c++11中,lambda表达式参数需要使用具体的类型声明。
auto f = [] (int a) { return a; }
在c++14中,lambda表达式参数可以直接为auto。
auto f = [] (auto a) { return a; }; cout << f(1) << endl; cout << f(2.3f) << endl;
3、变量模板
c++14支持变量模板。
template<class T> constexpr T pi = T(3.1415926535897932385L); int main() { cout << pi<int> << endl; // 3 cout << pi<double> << endl; // 3.14159 return 0; }
4、别名模板
c++14支持别名模板。
template<typename T, typename U> struct A { T t; U u; }; template<typename T> using B = A<T, int>; int main() { B<double> b; b.t = 10; b.u = 20; cout << b.t << endl; cout << b.u << endl; return 0; }
5、constexpr的限制
1)c++14相较于c++11减少了限制:
c++11和c++14中constexpr函数均可以使用递归。
constexpr int factorial(int n) { // C++14 和 C++11均可 return n <= 1 ? 1 : (n * factorial(n - 1)); }
c++14还可以使用局部变量和循环。
constexpr int factorial(int n) { // C++11中不可,C++14中可以 int ret = 0; for (int i = 0; i < n; ++i) { ret += i; } return ret; }
c++11中constexpr函数中必须把所有东西放在一个单独的return语句中。
constexpr int func(bool flag) { // C++14 和 C++11均可 return 0; }
c++14中constexpr函数没有上述限制。
constexpr int func(bool flag) { // C++11中不可,C++14中可以 if (flag) return 1; else return 0; }
6、[[deprecated]]标记
c++14中增加deprecated标记,修饰类、变量、函数等。编译时产生警告,提醒用户该标记修饰的内容未来可能会被丢弃。
struct [[deprecated]] A { }; int main() { A a; return 0; }
7、二进制字面量与字面量分隔符
c++14引入了二进制字面量和字面量分隔符。
int a = 0b0001'0011'1010; double b = 3.14'1234'1234'1234;
8、std::make_unique
c++11中有std::make_shared,c++14增加了std::make_unique。
struct A {}; std::unique_ptr<A> ptr = std::make_unique<A>();
9、std::shared_timed_mutex与std::shared_lock
c++14通过std::shared_timed_mutex和std::shared_lock来实现读写锁,保证多个线程可以同时读,但是写线程必须独立运行,写操作和读操作不可同时进行,这种情况下才能从shared_mutex中获取性能优势。
c++11 中互斥量
互斥量 | 说明 |
std::mutex | 独占的互斥量,不能递归使用 |
std::timed_mutex | 有超时能力的独占互斥量,不能递归使用 |
std::recursive_mutex | 递归互斥量 |
std::recursive_timed_mutex | 有超时能力的递归互斥量 |
c++14互斥量管理类-锁
- shared_lock是read lock。搭配std::shared_mutex使用,被锁定后允许其它线程执行同样被shared_lock的代码。
- lock_gurd和unique_lock是write lock。被锁定后,不允许其它线程执行被share_lock或unique_lock的代码。
通常这样定义:
typedef std::shared_lock<std::shared_mutex> ReadLock;
typedef std::lock_guard<std::shared_mutex> WriteLock;
实现方式:
struct ThreadSafe { mutable std::shared_timed_mutex mutex_; int value_; ThreadSafe() { value_ = 0; } int get() const { std::shared_lock<std::shared_timed_mutex> lock(mutex_); return value_; } void increase() { std::unique_lock<std::shared_timed_mutex> lock(mutex_); value_ += 1; } };
10、 std::integer_sequence
表示一个编译时的整型序列。
11、std::exchange
以 new_value
替换 obj
的值,并返回 obj
的旧值。注意与std::swap的区别。
vector<int> v{4,5,6,7}; vector<int> x = std::exchange(v, {1,2,3,4}); cout << v.size() << endl; for (int a : v) { cout << a << " "; } cout<<endl; for (int a : x) { cout << a << " "; }
12、std::quoted
c++14引入std::quoted用于给字符串添加双引号。
string str = "hello world"; cout << str << endl; cout << std::quoted(str) << endl; /* 输出 * hello world * "hello world" */