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::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 << " ";
}
11、std::quoted
c++14引入std::quoted用于给字符串添加双引号。
string str = "hello world";
cout << str << endl;
cout << std::quoted(str) << endl;
/* 输出
* hello world
* "hello world"
*/