引言
C++11 标准是语言发展的重要里程碑,引入了大量革命性特性。本文系统梳理 C++11 的核心新增特性,涵盖统一列表初始化、声明优化(auto/decltype/nullptr)、STL 容器与接口扩展,以及右值引用、移动语义和完美转发等底层机制。
历史背景
C++ 首个国际标准发布于 1998 年(C++98)。C++11 在此基础上修复了诸多缺陷,并引入范围 for、智能指针等新特性。
统一的列表初始化
C++11 扩大了花括号 {} 的使用范围,适用于内置类型和用户自定义类型。使用列表初始化时,可添加等号 =,也可不添加。
int y = {2};
int y{2};
struct Point {
Point(int x, int y) : _x(x), _y(y) {}
int _x, _y;
};
Point p1 = {1, 1};
Point p1{1, 1};
const Point& r = {3, 3};
initializer_list
当 auto 用于初始化列表 {...} 时,编译器优先推导为 std::initializer_list<T> 类型。一般容器的构造函数和赋值操作符支持此类型。
vector<int> v1 = {1, 2, 3, 4, 3};
注意:initializer_list 仅引用常量区数组,不存储数据。多参数构造函数的隐式转换规则与此不同。
声明优化
C++11 新增了 auto, nullptr 和 decltype。
- nullptr:空指针常量,替代宏定义的
NULL,避免类型歧义。 - decltype:关键字用于推导表达式指定的类型,可作为模板实参或变量类型定义。
int a = 0;
double b = 1.0;
decltype(a * b) c = 2;
STL 变化
新容器
增加了 array, forward_list, unordered_map, unordered_set。原生数组建议使用 vector 代替以避免越界风险。
新接口
- 添加了
cbegin,cend,crbegin,crend等常量迭代器接口。 - 所有容器支持
initializer_list初始化及移动构造/赋值。 - 多数接口新增
emplace系列(如emplace_back),支持在原地构造对象。
新的类功能
- 移动语义:默认生成移动构造函数和移动赋值运算符重载。若未定义析构、拷贝构造/赋值,编译器自动生成移动版本。
- 成员初始值:允许在类定义时给成员变量指定缺省值。
- 控制关键字:
final(禁止继承),override(重写检查)。 - 函数控制:强制生成默认函数
= default,禁止生成= delete。
引用与移动语义
左值和右值
- 左值:可以取地址,通常可修改。
- 右值:不能取地址,不可修改(纯右值或将亡值)。
左值引用和右值引用
- 左值引用:
int &a = b;,给左值取别名。 - 右值引用:
double &&r = x + y;,给右值取别名。右值引用赋予对象左值属性(有地址且可修改)。
move 可将左值转为右值引用以触发移动语义。
移动构造
资源转移而非深拷贝。例如函数返回大对象时,移动构造可减少开销。
string func() {
string str("xxxx");
return str;
}
完美转发
万能引用 T&& 根据实参类型折叠为左值或右值引用。使用 std::forward<T>(t) 保留参数原始属性进行转发,确保在中间传递过程中不丢失右值属性。
template<typename T>
void PerfectForward(T&& t) {
Fun(std::forward<T>(t));
}


