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 第二版

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。