C++14 经常被看作是 C++11 的"完美补丁包"。它没有引入特别颠覆性的新概念,而是把 C++11 中一些用着不顺手的地方打磨得更流畅、更简洁了。
下面是几个最常用、最能提升日常编码效率的新特性:
1. 泛型 Lambda 表达式
本质: 以前写 Lambda(匿名函数)时,参数类型必须写死(比如必须是 int)。C++14 允许在参数里直接使用 auto,让一个 Lambda 能处理各种类型,就像写了一个小型的函数模板。
实际例子:
cpp
// C++11 写法:只能加两个 int
auto add_11 = [](int a, int b) { return a + b; };
// C++14 写法:可以加 int,也可以加 double
auto add_14 = [](auto a, auto b) { return a + b; };
std::cout << add_14(1, 2) << "\n"; // 输出 3
std::cout << add_14(1.5, 2.3) << "\n"; // 输出 3.8
2. 初始化捕获(Init Capture)
本质: 解决了 C++11 Lambda 捕获变量时的痛点。它允许你在捕获外部变量时,给变量改个名字,或者直接"移动(move)"一个不可拷贝的资源(比如智能指针)进 Lambda 内部。
实际例子:
cpp
#include <memory>
#include <iostream>
auto ptr = std::make_unique<int>(42); // 一个不可拷贝的智能指针
// C++14:直接把 ptr 移动(move)进 Lambda,并改名为 p
auto lambda = [p = std::move(ptr)]() {
std::cout << *p << "\n";
};
lambda(); // 输出 42
3. 变量模板(Variable Templates)
本质: 以前如果想定义一个适配各种类型的常量(比如圆周率 PI),得用类模板或函数模板来绕一下。C++14 允许直接把变量变成模板,语义非常直观。
实际例子:
cpp
// 定义一个泛型的 PI 常量
template<typename T>
constexpr T pi = T(3.1415926535);
// 想要什么类型的 PI 直接取用
double pi_d = pi<double>;
float pi_f = pi<float>;
4. std::make_unique
本质: 这是一个标准库的补充。C++11 已经有了 make_shared,但唯独漏掉了 unique_ptr 的工厂函数。C++14 补齐了这个短板,让你不用手动写 new,代码更安全、更简洁。
实际例子:
cpp
#include <memory>
// C++11 写法(略显繁琐)
std::unique_ptr<int> ptr1(new int(10));
// C++14 写法(推荐,更安全)
auto ptr2 = std::make_unique<int>(10);
5. 二进制字面量与数字分隔符
本质: 纯粹的"语法糖",目的是让代码更好读。支持用 0b 开头写二进制数,并且允许在长数字里加单引号 ' 作为分隔。
实际例子:
cpp
// 二进制字面量
int mask = 0b1100'0011;
// 数字分隔符(编译器会忽略单引号,纯粹给人看的)
long long money = 9'223'372'036'854'775'807LL;
6. 更宽松的 constexpr
本质: C++11 的 constexpr(编译期常量计算)限制非常多,函数里基本只能写一行 return。C++14 放开了限制,允许在 constexpr 函数里写 if 判断、for/while 循环等普通逻辑。
实际例子:
cpp
// C++14 中,可以在编译期计算的函数里写循环和判断了
constexpr int factorial(int n) {
if (n <= 1) return 1;
return n * factorial(n - 1);
}
int arr[factorial(5)]; // 直接在编译期算出 120,用来定义数组大小
7. 函数返回类型推导
本质: 编译器变聪明了。对于普通函数,你不再需要显式指定返回类型,直接用 auto,编译器会根据你的 return 语句自动推导出正确的类型。
实际例子:
cpp
// 不用写 int,编译器自动知道返回的是 int
auto add(int a, int b) {
return a + b;
}
这些特性让 C++14 的代码写起来比 C++11 更加顺手,同时也保持了极高的运行效率。建议在日常开发中优先尝试使用它们!