C++11 引入了列表初始化和变量类型推导两大核心特性,彻底解决了传统 C++ 初始化语法混乱、类型书写冗长的问题,同时大幅提升了代码的安全性和简洁性,是现代 C++ 编程的基础必备知识。
1.列表初始化
1. 核心定义
C++11 推出统一初始化语法,使用大括号 {} 对所有类型(基本类型、数组、类、STL 容器等)进行初始化,也叫大括号初始化/统一初始化。
它解决了传统 C++ 初始化方式混乱(= 赋值初始化、() 直接初始化)的问题,是现代 C++推荐的默认初始化方式。
2. 基础语法
两种等价写法(编译器会优化拷贝语义,无性能差异):
cpp
// 1. 直接列表初始化
Type obj{ 参数... };
// 2. 拷贝列表初始化
Type obj = { 参数... };
3. 最大优势:禁止窄化转换(安全核心)
窄化转换:高精度类型向低精度类型转换、丢失数据的隐式转换(如 double→int、int→char 溢出)。
传统 = 初始化:静默丢失数据,无任何报错;
列表初始化:编译期直接报错,从根源避免数据丢失。
cpp
// 传统初始化:危险!静默窄化,无报错
int a = 3.99; // a=3,小数被截断
char c = 1000; // 超出char范围,溢出
// 列表初始化:安全!编译报错,禁止窄化
int b{3.99}; // 错误:double 转 int 是窄化转换
char d{1000}; // 错误:int 超出 char 取值范围
4. 全场景适用示例
列表初始化可以初始化所有 C++ 类型,这是它的核心价值:
cpp
#include <iostream>
#include <vector>
#include <map>
#include <string>
using namespace std;
// 自定义结构体(聚合类型)
struct Student {
int id;
string name;
};
// 自定义类
class Test {
public:
Test(int x, double y) { /* 构造函数 */ }
};
int main() {
// 1. 基本数据类型 + 空列表零初始化
int x{10}; // 普通初始化
int zero{}; // 空列表:零初始化 → zero=0
double pi{3.14};
// 2. 数组/聚合类型
int arr[]{1,2,3,4}; // 数组初始化
Student s{101, "张三"}; // 结构体直接初始化
// 3. STL容器(最常用场景)
vector<int> vec{1,2,3,4}; // 直接初始化容器元素
map<int, string> mp{{1,"a"}, {2,"b"}}; // 嵌套初始化
// 4. 自定义类对象
Test t{20, 5.5};
return 0;
}
5. 关键避坑指南
优先匹配 std::initializer_list 构造函数
如果类定义了接收 std::initializer_list 的构造函数,列表初始化会优先调用它,而非普通构造函数:
cpp
#include <vector>
using namespace std;
vector<int> v1(5); // 普通():创建5个值为0的元素
vector<int> v2{5}; // 列表{}:创建1个值为5的元素(核心区别)
2.变量类型推导
C++11 允许编译器自动推导变量类型,无需手动书写冗长的类型名,核心关键字:
auto:推导变量的类型(最常用);
(1)核心规则
必须初始化:编译器通过初始值推导类型,无初始值会编译报错;
忽略顶层 const,保留底层 const:
顶层 const:变量本身不可修改(如 const int a);
底层 const:指向的对象不可修改(如 const int* p)。
(2)基础示例
cpp
// 基本类型推导
auto a = 10; // int
auto pi = 3.14; // double
auto str = "hello"; // const char*
// 简化冗长类型(最实用场景:迭代器)
vector<int> vec{1,2,3};
auto it = vec.begin(); // 等价于 vector<int>::iterator it
(3)const 推导规则
顶层 const:变量本身不能被修改(自己是只读的)
底层 const:变量指向 / 引用的对象不能被修改(自己可改,目标只读)
cpp
const int num = 100;
auto x = num; // x 是 int(顶层const被忽略)
x = 200; // 合法
auto& y = num; // y 是 const int&(底层const保留)
// y = 200; // 错误!只读引用,不可修改
auto* p = # // p 是 const int*(底层const保留)
(4)auto + 列表初始化(特殊规则)
cpp
auto x{1}; // 单元素列表 → 推导为 int
auto lst = {1,2,3}; // 多元素列表 → 推导为 std::initializer_list<int>
谢谢