C++14 新特性

C++14 是 C++11 的小版本更新,主要是完善和补充,核心特性不多但很实用。


C++11 只有 lambda 可以用 auto 推导返回值,C++14 扩展到所有函数:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
// C++14:自动推导返回 int
auto add(int a, int b) {
    return a + b;
}

// 多个 return 必须类型一致
auto f(bool flag) {
    if (flag) return 1;    // int
    else return 2;         // OK,都是 int
    // return 3.14;        // ERROR,类型不一致
}

注意:

  • 递归函数不能用 auto 返回值推导(除非先有前置声明)
  • 有多个 return 语句时,所有 return 的类型必须相同

C++11 的 lambda 参数必须写具体类型,C++14 可以用 auto:

1
2
3
4
5
6
7
8
// C++14:参数用 auto,相当于模板函数
auto add = [](auto a, auto b) {
    return a + b;
};

add(1, 2);       // int
add(1.5, 2.3);   // double
add(string("a"), string("b"));  // string

本质: 编译器自动生成一个模板函数对象。


之前只有类模板、函数模板,C++14 新增变量模板:

1
2
3
4
5
6
7
// 定义一个 pi 变量模板
template<typename T>
constexpr T pi = T(3.1415926535897932385);

// 使用
float  r1 = pi<float>;
double r2 = pi<double>;

最经典的应用:std::is_same_v<T, U> 就是 C++17 基于变量模板做的。


C++14 允许聚合体中含有默认成员初始化器时,仍然可以用花括号初始化:

1
2
3
4
5
6
7
struct Point {
    int x = 0;
    int y = 0;
};

Point p1{1, 2};  // C++11 不允许,C++14 可以
Point p2{};      // x=0, y=0,用默认值

解决转发函数的返回值问题:

1
2
3
4
5
// 用 auto 会丢失引用
auto f1() -> decltype(expr) { return expr; }  // C++11 写法

// C++14 简化写法
decltype(auto) f2() { return expr; }

区别:

  • auto:会去掉引用和顶层 const
  • decltype(auto):完美保留表达式的原始类型
1
2
3
4
5
int x = 42;
int& ref = x;

auto a = ref;            // int
decltype(auto) b = ref;  // int&

C++11 有 make_shared 但漏掉了 make_unique,C++14 补上:

1
auto p = std::make_unique<int>(42);  // 推荐,比 new 安全

读写锁的超时版本,C++17 又加了 shared_mutex。

模板元编程工具,用于展开参数包:

1
2
template<typename T, T... Is>
struct integer_sequence { ... };

日常开发用得少,库作者用得多。

赋值并返回旧值:

1
2
3
std::vector<int> v{1, 2, 3};
auto old = std::exchange(v, {4, 5, 6});
// old = {1,2,3}, v = {4,5,6}

特性说明
二进制字面量0b1010 表示十进制 10
数字分隔符1'000'000 可读性更好
lambda 初始化捕获C++14 可以在捕获列表里初始化新变量
1
2
3
// 初始化捕获(init capture)
int x = 10;
auto f = [y = x + 1]() { return y; };  // y = 11

C++14 是一个过渡版本,特性不多但都很实用:

  • 函数返回值 auto:写起来更简洁
  • 泛型 lambda:配合 auto 参数,写算法更方便
  • decltype(auto):完美转发返回值
  • make_unique:终于补上了
  • 变量模板:为后续标准库简化铺路

相关内容