C++11 前,不同類型初始化語法不一致:
T obj = {val1, val2};T obj(arg1, arg2);這導致模板代碼難以統一處理初始化,且隱式窄化轉換(如 double→int)隱患難察覺。
C++11 引入 std::initializer_list,統一使用 { ... } 初始化所有類型:
struct Man { string name; int age; };
class Woman { string name; int age;
public: Woman(string n, int a): name(n), age(a) {} };
Man m1 = {"Alice", 20}; // 聚合初始化
Woman w1 = {"Bob", 25}; // 類初始化(需構造函數匹配)
Woman w2 {"Carol", 30}; // 直接列表初始化(C++11)
vector<int> v = {1, 2, 3}; // 容器初始化
int* arr = new int[3]{1,2,3};// 動態陣列初始化
列表初始化禁止窄化轉換:
void func(int x);
func(3.14); // C++98: 隱式截斷為 3,僅警告
// func({3.14}); // C++11: 編譯錯誤!窄化被禁止
int x = {3.14}; // 錯誤:double→int 窄化
int y = {3}; // 正常:int→int 無窄化
注意:若類有 initializer_list 構造函數,列表初始化優先匹配它,可能改變語義。
class Widget {
int data[4];
public:
Widget() : data{1, 2, 3, 4} {} // 直接初始化成員陣列
};
auto x = {1, 2}; // x 是 std::initializer_list<int>
auto y = {3.14}; // y 是 std::initializer_list<double>
// auto z = {1, 2.0}; // 錯誤:類型推導衝突
initializer_list 重載T{args...}:統一構造語法統一初始化是 C++11 核心特性之一,徹底解決了初始化語法碎片化,提升了代碼安全性與可讀性。