本文是一篇C++11关于变量的改进
关键词
std::initializer_list
解释
在 C++98/03 中的对象初始化方法有很多种,这无疑增大了学习难度。这中情况在C++11中终于得到解决。
先看看没有C++11的时候
//初始化列表
int i_arr[3] = { 1, 2, 3 }; //普通数组
struct A
{
int x;
struct B
{
int i;
int j;
} b;
} a = { 1, { 2, 3 } }; //POD类型
//拷贝初始化(copy-initialization)
int i = 0;
class Foo
{
public:
Foo(int) {}
} foo = 123; //需要拷贝构造函数
//直接初始化(direct-initialization)
int j(0);
Foo bar(123);
int data = 0; //赋值初始化
int data = {0}; //花括号初始化
int data(0); //构造初始化
int data{0}; //花括号初始化
这些不同的初始化方法,都有各自的适用范围和作用。最关键的是,这些种类繁多的初始化方法,没有一种可以通用所有情况。
为了统一初始化方式,并且让初始化行为具有确定的效果,C++11 中提出了列表初始化(List-initialization)的概念。
统一的初始化
举个小例子看看C++11变长初始化列表是怎么用的
#include <initializer_list>
class MagicFoo{
public:
std::vector<int> vec;
MagicFoo(std::initializer_list<int> list){
for (std::initializer_list<int>::iterator it = list.begin();
it!= list.end(); ++it)
vec.push_back(*it);
}
};
int main(){
// after C++11
MagicFoo magicFoo = {1, 2, 3, 4, 5};
for (auto it : magicFoo.vec)
std::cout << it << std::endl;
}
这里需要注意的是,虽然使用了等于号,但它仍然是列表初始化,因此,私有的拷贝构造并不会影响到它。
总结
C++11统一了所有初始化方式,都变成了下面的形式:
Foo a3 = { 123 };
Foo a4 { 123 };
除了上面所述的内容之外,列表初始化还可以直接使用在函数的返回值上:
struct Foo
{
Foo(int, double) {}
};
Foo func(void)
{
return { 123, 321.0 };
}
这里的 return 语句就如同返回了一个 Foo(123, 321.0)。
关注公众号获取更多信息: