c++11---统一的初始化和初始化列表
2014-04-22 20:02
363 查看
在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);
P p{77,5} ; //call p(std::initialize_liat<int> );
p r{77,5,42}; //call p(std::initialize_liat<int> );
p s = {77 , 5}; //call p(std::initialize_liat<int> );
没有构造函数的初始化列表,构造函数传递两个整形通过p,q两个形参。
因为初始化列表,explicit显示构造变成实质性的,所以现在你可以通过一个自动类型对多个值操作, 当一个初始化列表使用=语法。
class P
{
public:
p(int a , int b)
{
...
}
explicit P(int a , int b , int c){
....
}
};
p x{(77,5); //ok
P y{77 , 5}; //ok
P z{77 , 5 , 42}; //ok
p v = {77 , 5}; //ok
p k = {77 , 5 , 42}; // 因为显式调用标记
void fp(const p&);
fp({75 , 2}); //ok
fp({75,6 , 42}) ; //error 因为显式调用标记
fp(p{47,11}); //ok
fp(p{33 , 3 , 33}); //ok
相同的方法,显式构造使用一个初始化列表是无力的内含的0 , 1 , 或者更多的初始化值
初始化经常使用括号,或者是使用大括号,或者是复赋值操作。
因为这个原因,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);
P p{77,5} ; //call p(std::initialize_liat<int> );
p r{77,5,42}; //call p(std::initialize_liat<int> );
p s = {77 , 5}; //call p(std::initialize_liat<int> );
没有构造函数的初始化列表,构造函数传递两个整形通过p,q两个形参。
因为初始化列表,explicit显示构造变成实质性的,所以现在你可以通过一个自动类型对多个值操作, 当一个初始化列表使用=语法。
class P
{
public:
p(int a , int b)
{
...
}
explicit P(int a , int b , int c){
....
}
};
p x{(77,5); //ok
P y{77 , 5}; //ok
P z{77 , 5 , 42}; //ok
p v = {77 , 5}; //ok
p k = {77 , 5 , 42}; // 因为显式调用标记
void fp(const p&);
fp({75 , 2}); //ok
fp({75,6 , 42}) ; //error 因为显式调用标记
fp(p{47,11}); //ok
fp(p{33 , 3 , 33}); //ok
相同的方法,显式构造使用一个初始化列表是无力的内含的0 , 1 , 或者更多的初始化值
相关文章推荐
- C++11之统一初始化
- C++11的初始化列表
- C++11特性:列表初始化:VS2010中vector<string>的初始化方式
- C++11 理解 (六) 之 统一的初始化
- c++11——列表初始化
- 第6课 列表初始化(1)_统一初始化
- C++11新特性之列表初始化
- 关于c++的class(偏c++11以前,构造、静态成员、const、初始化列表、友元、内联、template)
- 【读书笔记】【深入应用C++11】1.3 列表初始化
- C++11新标准之二:初始化列表
- c++11之初始化列表
- C++11新标准学习之花括号初始化列表
- 关于C++11的统一初始化语法示例详解
- C++11 新特性(5) 统一初始化
- C++11 新特性 braced-init-list (List Initialization) 列表初始化
- C++11特性(5):explicit、列表初始化
- C++11特性--统一的初始化,std::initializer_list
- C++11系列学习之七---------初始化列表
- 现代c++之列表初始化/统一初始化
- [C++11笔记001]修改通用库中的XDynamicArray,使它可以支持C++11的初始化列表和for循环