1.C++中指定初始化值的方式有4种方式: (1)小括号 int x(0); (2)等号 int x = 0; (3)大括号 int x{0}; (4)等号和大括号 int x = {0}; 2.C++11统一初始化, 即使用大括号初始化方式, 其使用场景主要有以下3种: (1)类非静态成员指定默认值 (2)为容器赋值 vector<int> vec = {1, 2, 3}; (3)对不支持拷贝操作的对象赋值 unique_ptr<int> p{}; 之所以称为统一初始化, 其原因在于上述3种使用场景中, 第(1)种不支持小括号; 第(2)种不支持等号和小括号; 第(3)种不支持等号. 3.统一初始化的优势: (1)能禁止内置类型之间的隐式窄化转换, 即表达式无法保证接收对象能够表达其值, 则代码不能通过编译(至少会给出编译警告)! 如 double d{}; long x{d}; (2)可以有效解决小括号定义对象却解析为声明函数的问题. 如 int x(); 声明为函数 x 而不是定义变量, 使用统一初始化则不会出现问题. 4.统一初始化的不足: 不足之处在于重载匹配过程变得更加复杂, 难于理解: (1)对重载函数, 统一初始化使用大括号会将数据声明为 initializer_list 对象, 只有重载匹配过程中, 无法找到 initializer_list类型的形参时, 其它函数才会成为可选函数. 因此, 对声明了 initializer_list 形参的重载函数, 则使用统一初始化的代码会优先匹配该函数, 而其他更精确匹配的版本可能没有机会被匹配. 其中需要特别注意的是经常使用容器 vector. 如 vector<int> vec(10, 2) 和 vector<int> vec{10,2}, 前者是含有 10 个元素的对象, 而后者是只包含 10 和 2 两个元素的对象. (2)对于构造函数, 空大括号构造一个对象时, 不是匹配 initializer_list 形参的版本, 而是默认构造函数. class Test { public: Test() { PRINT_POS(); } template <typename T> Test(std::initializer_list<T> ls) { Q_UNUSED(ls); PRINT_POS(); } }; 进行如下调用时, Test t1{}; Test t2{1}; // Test t3{{}}; //error: no matching function for call to 'Test::Test(<brace-enclosed initializer list>)' Test t4{{1}}; Test t5({}); 其中 t1 和 t5 使用默认构造函数, t2 和 t4 使用列表初始化构造函数, t3 则不能定义. (3)对于 initializer_list 模板特例化版本, 情形较第2种又有所不同. a. void foo(int); b. template <typename T> void foo(initializer_list<T> lsi); 当进行以下函数调用 foo(0); foo({}); foo({0}); 时, 分别调用的是 a, a, b. c. void foo(int); d. void foo(initializer_list<int> lsi); 当进行以下函数调用 foo(0); foo({}); foo({0}); 时, 分别调用的是 c, d, d.