C++14 新特性

概述

C++14 是对 C++11 的”完善型”升级:没有革命性新语法,但把 11 里受限的功能放开,让日常写代码更顺手。以下按主题整理。

一、函数返回类型推导

// C++11:需要尾置返回类型
auto add(int a, int b) -> int { return a + b; }

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

// decltype(auto):保留引用性
int& get_ref(int& x) { return x; }
decltype(auto) get_ref14(int& x) { return x; }   // 返回类型仍是 int&

二、泛型 Lambda 与捕获表达式

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

// C++14 泛型 Lambda:参数用 auto
auto lambda14 = [](auto x, auto y) { return x + y; };
int i = lambda14(3, 4);          // int 版本
double d = lambda14(3.5, 4.5);   // double 版本

// 捕获表达式:捕获"表达式结果"而不是变量
int x = 10;
auto lambda = [value = x * 2]() { return value; };  // 捕获 20

三、constexpr 增强

C++11 的 constexpr 函数只能写单条 return,基本不可用;C++14 放开局部变量、循环、if,编译期计算才真正落地:

constexpr int factorial(int n) {
    int result = 1;
    for (int i = 1; i <= n; ++i) result *= i;
    return result;
}
constexpr int fact5 = factorial(5);   // 编译期算出 120

四、其他实用特性

变量模板

template<typename T>
constexpr T pi = T(3.1415926535897932385);
float f = pi<float>;   // 按类型实例化

字面量增强

int x = 0b101010;          // 二进制字面量 = 42
int million = 1'000'000;   // 数字分隔符,可读性

[[deprecated]] 属性

[[deprecated("Use new_func() instead")]]
void old_func() {}
old_func();   // 编译器警告

std::make_unique

auto up = std::make_unique<int>(42);   // C++11 只有 make_shared
auto sp = std::make_shared<int>(42);

std::exchange / std::quoted

int x = 10;
int old = std::exchange(x, 20);   // old=10, x=20

std::string s = "Hello";
std::cout << std::quoted(s);      // 输出 "Hello"(带引号)

读写锁:shared_timed_mutex

std::shared_timed_mutex mtx;
// 读锁(共享,可并发)
std::shared_lock lock(mtx);
// 写锁(独占)
std::unique_lock lock(mtx);

std::cbegin / std::cend

auto it = std::cbegin(v);   // 比 v.cbegin() 更通用(数组也能用)

聚合初始化与 tuple 按类型取元素

struct Point { int x, y; };
Point p{1};                 // p.x=1, p.y=0

auto t = std::make_tuple(1, 2.5, "hello");
double d = std::get<double>(t);   // 按类型取(类型需唯一)

实战体会

泛型 lambda 是模板样板代码的终结者。写排序、遍历、回调时,C++11 里每种参数类型都要单独写模板函数或函数对象;C++14 的泛型 lambda 让 auto 参数进 lambda,配合算法库几乎省掉一半重复代码。

返回类型推导在模板库里要谨慎。普通函数用 auto 推导很爽,但一旦涉及 SFINAE 和模板重载,隐式推导的返回类型会让代码难以预测、编译报错更难读。模板元编程相关函数老老实实写显式返回类型。

constexpr 增强让编译期计算真正可用。C++11 的 constexpr 只能单条 return,基本没法用;C++14 放开循环和分支后,我把配置解析、容量计算这类工作挪到了编译期,运行期零成本。

滚动至顶部