C++11中uniform initialization和initializer_list
C++11中出现了uniform initialization的概念:
int a1 = {1};//ok int a2 = {1.0};//错误,必须收缩转换 int array1[] = {1,2,3,4};//ok int arrya2[] = {1.0,2.0,3.0,4.0};//ok
注意a2的初始化错误和array2的正确对比。一方面uniform initialization要求初始化的类型必须是一致的,但一方面新的C++标准必须兼容C++98,而在C++98中array2的初始化是合法的。
新的C++11标准还增加了一个std::initializer_list<>的类,在构造函数中可以传入此参数类型
#include<iostream> class A { A(int , int) { std::cout<<"int,int"<<std::endl; } A(std::initializer_list<int>)//注意不是引用! { std::cout<<"initializer_list<int>"<<std::endl; } }; int main() { A a1(1,1);//int int A a2{1,1};//initializer_list<int> A a3 = {1,1};//initializer_list<int> return 0; }
注意到a3调用的是initializer_list<int>版本的构造函数。
#include<iostream> class A { explicit A(int , int) { std::cout<<"int,int"<<std::endl; } A(std::initializer_list<int>)//注意不是引用! { std::cout<<"initializer_list<int>"<<std::endl; } }; class B { B(int , int) { std::cout<<"int,int"<<std::endl; } explicit B(std::initializer_list<int>)//注意不是引用! { std::cout<<"initializer_list<int>"<<std::endl; } }; class C { explicit C(int , int) { std::cout<<"int,int"<<std::endl; } explicit C(std::initializer_list<int>)//注意不是引用! { std::cout<<"initializer_list<int>"<<std::endl; } }; int main() { A a = {1,1};//initializer_list<int> B b = {1,1};//int,int C c = {1,1};//error:无法从initializer_list到C return 0; }
上面B的构造函数因为initializer_list版本被设为explicit,构造函数变为B(int,int)的版本,我们可以推断出:
1.initializer_list的优先级要高于指定参数的构造函数
2.uniform initialization实际上是传递了一个initializer_list对象给构造函数,发生了一系列隐式转换。(由class C的构造函数提示的错误信息可以判断出)
——————————————————————————————————————————————————————————————————————
参考资料:《C++标准库——自学教程与参考手册》Nicolai M.Josuttis 第二版