在c++11以前,程序员,或者初学者经常会感到疑惑关于怎样去初始化一个变量或者是一个对象。
初始化经常使用括号,或者是使用大括号,或者是复赋值操作。
因为这个原因,c++11提出了统一初始化,以为着使用这初始化列表,下面的做法都是正确的。
int value[] {1 , 2 , 3};
std::vector<int> vi {2 , 3 , 4 , 56, 7};
std::vector<std::string> cities {"Berlin" , "New York " , "london " , "cairo"};
std::complex<double> c{4.0 , 3.0}; //相当于c(4.0 , 3.0);
一个初始化列表强制使用赋值操作, 也就是以为着每个变量都是一个默认的初始化值,被初始化为0(NULL 或者是 nullptr)
如下:
int i; //这是一个未定义的行为
int i{}; //i调用默认的构造函数为i赋值为0
int *p; //这是一个未定义的行为
int *p{} ;// p被初始化为一个nullptr
然后,精确的初始化,它们减少精度,或者是一个补充值被修改,是不可能的。
例如:
int x1(5.3); // 5
int x2 = 5.3 //5
int xi{5.0} //精确地 所以会出现error
int x4 = {5.3} // 精确地 所以会出现error
char ci{7};
char c9{9999}; //error 9999不合适是一个char类型
正如你所看见的,去检查是否是精确地,尽管变量或许是被认定的, 如果变量发生在编译时期。
为了支持初始化列表和用户自定义类型结合,c++11提供了类模板class templete std::initialize_list<> , 可以被用来初始化一个值或者在任何地方你想提供一组值。
void print(std::initialize_list<int> vals)
{
for(auto p= vals.begin() ; p != vals.end() , ++p )
{
std::cout<<*p<<std::endl;
}
}
print(2 , 3, 4, 5,6 , 7);
2
3
4
5
6
7
作为程序的输出
当构造函数为一个特殊的成员或者是一个初始化列表,初始化列表是被作为首选的
class P
{
public:
p(int , int);
p(std::initialize_liat<int> );
};
P p(77,5); //call p(int , int);