C++14 新特性

C++14 新特性

C++14 的定位

C++14(ISO/IEC 14882:2014)没有引入新概念,它把 C++11 里”能用但不顺手”的能力放开:函数返回类型推导、泛型 lambda、constexpr 循环。属于完善型升级,从 11 迁移成本极低。

C++14 改进概览:constexpr 对比与六个新特性
图 1:C++14 改进概览——constexpr 从”一条 return”放开到循环,另有六个常用新特性

函数返回类型推导

// C++11:必须写尾置返回类型
auto add11(int a, int b) -> int { return a + b; }

// C++14:直接推导
auto add14(int a, int b) { return a + b; }

// decltype(auto):保留引用性
int x = 0;
decltype(auto) r = (x);   // int&,推导结果带引用

模板函数里最有用:decltype(auto) 把模板参数的引用性原样带出。注意别让推导结果带着局部变量的引用返回——那是悬垂引用。

泛型 Lambda 与初始化捕获

// C++11:lambda 参数类型必须写明
auto lambda11 = [](int x, int y) { return x + y; };

// C++14:参数用 auto,等价于一个模板 lambda
auto lambda14 = [](auto x, auto y) { return x + y; };
int i = lambda14(3, 4);         // int 实例
double d = lambda14(3.5, 4.5);  // double 实例

// 初始化捕获:捕获的是"表达式的值"而不是变量
int factor = 10;
auto f = [mul = factor * 2](int x) { return x * mul; };  // 捕获 20

初始化捕获还能捕获只可移动的对象(unique_ptr、文件句柄):[p = std::move(ptr)],C++11 里做不到。

constexpr 增强

// C++11:函数体只能一条 return,基本不可用
constexpr int sq11(int x) { return x * x; }

// C++14:允许局部变量、循环、if 分支
constexpr int factorial(int n) {
    int result = 1;
    for (int i = 1; i <= n; ++i)
        result *= i;
    return result;
}
static_assert(factorial(5) == 120, "");   // 编译期算出 120

这之后编译期计算才真正落地:配置表、哈希、查表算法都能在编译期算好,运行时零开销。

变量模板

template <typename T>
constexpr T pi = T(3.14159265358979323846);

double r = 2 * pi<double>;   // 按类型实例化
float  s = pi<float>;

常量按类型取不同精度,标准库的 std::is_integral_v<T> 这类 _v 后缀变量模板就是它的产物。

字面量增强

int a = 0b1010;       // 二进制字面量:10
int b = 1'000'000;    // 数字分隔符:一百万,大数可读性
int c = 0xFF'FF;      // 位掩码按字节分组

其他实用特性

[[deprecated]] 属性

[[deprecated("用 new_func 替代")]]
void old_func();

old_func();   // 编译告警,提示替代方案

std::make_unique

C++11 有 make_shared 却没有 make_unique,14 补上。统一用 make_* 工厂:省一次显式 new,异常安全(参数求值顺序不会泄漏)。

std::exchange

// 读旧值 + 写新值合成一步,写移动赋值运算符时常用
old = std::exchange(ptr, nullptr);   // old 拿到旧值,ptr 被置空

读写锁 shared_timed_mutex

多读单写场景:读用 shared_lock 并发进入,写用 unique_lock 独占。

std::cbegin / std::cend

显式获取只读迭代器,模板泛型代码里避免 const 推导问题。

实战体会

C++14 是迁移性价比最高的一次升级:没有破坏性改动,却能删掉大量样板代码。泛型 lambda 让我把散落各处的函数对象清理掉了大半;constexpr 增强则让”配置即代码”真正可行——编译期算好的表运行时直接查,连初始化检查都由编译器代劳。

滚动至顶部