C++11 右值引用与移动语义详解
背景与历史发展
C++11 是 C++ 标准自 C++98 以来最重要的更新之一。在 ISO 于 2011 年正式采纳前,它曾被称为 C++0x。这次更新标准化了许多实践,并引入了大量新特性,极大地提升了 C++ 的性能和表达能力。
注意:语言标准的普及需要时间。大多数公司目前仍在使用 C++11 或 C++14,而 C++17 及更高版本正在逐步落地。编译器对特性的支持程度往往滞后于标准制定,实际开发中需关注目标平台的编译器版本。
列表初始化:{} 的演变
C++98 中的初始化
在旧标准中,数组和结构体通常使用 {} 进行初始化,但行为较为局限。例如:
int array[] = { 1, 2, 3 };
Point p = { 1, 2 }; // 部分编译器支持,但不统一
C++11 的统一初始化
C++11 引入了列表初始化(List Initialization),试图实现一切对象皆可用 {} 初始化。这不仅适用于内置类型,也适用于自定义类型。
// 省略等号
int i{ 10 };
Date d{ 2025, 11, 15 };
vector<int> v{ 1, 2, 3 };
这种语法在容器构造时尤为方便,避免了多重构造函数的冗余。
std::initializer_list
为了支持任意数量的参数初始化,C++11 提供了 std::initializer_list。其底层是一个指向数组的指针结构,内部包含两个指针分别指向起始和结束位置。
auto il = { 10, 20, 30 };
// 类型推断为 std::initializer_list<int>
STL 容器(如 vector、map)通过接受 initializer_list 构造函数,实现了灵活的初始化方式。
引用机制:左值与右值
概念区分
- 左值(Lvalue):表示持久存在的对象,可以取地址。通常出现在赋值符号左侧。
- 右值(Rvalue):临时对象或字面量,不能取地址。通常出现在赋值符号右侧。
int a = 10;
b = a + ;


