c++11的列表初始化及其底层原理
在c++98中,只允许数组和结构体的元素使用列表进行初始化
但是在c++11中,可以使用列表对所有的元素进行初始化
在使用{}进行初始化的时候,可以添加=,也可以不添加=
int a = { 10 }; int b{ 10 }; int* pa = new int[4] {0}; int arr[3]{ 1,2,3 }; pair<int, string >{1, "222"}; //易错 unordered_map<string, int>{{"11", 1}, { "222", 2 }};这里map的内置类型是pair,pair可以使用{}初始化,map也可以使用{}初始化
并且自定义类型在构造的时候可以使用{}调用构造函数进行初始化
class A { public : A(int a,int b,int c) :_a (a), _b(b), _c(c) { } private: int _a; int _b; int _c; }; int main() { A a{1,2,3}; return 0; }易错:对于自定义类型必须是在创建的时候调用{}进行初始化
列如
A b; b{ 1,2,3 };则不能进行初始化,A b已经创建好对象,后面应该进行赋值而不能初始化
底层原理:
我们首先来看这一段代码:
auto il = { 10,20,30 }; cout << typeid(il).name() << endl; cout << sizeof(il) << endl;il因该是什么类型那,很明显{ 10,20,30 }是一个常量数组,,因此我们推测il可能是一个数组,
但结果显示为
il是一个initializer_list<int>的类型,这里是c++11新增添的内容,并且il的大小为8(我这里采用的是x86),为什么是8那
首先我们来看一看initializer_list是什么
initializer_list可以看作一个容器,包含构造方法和迭代器,initializer_list的原理其实是这样的\
其内部有一个头指针和一个尾指针,头指针指向这个常量数组的开始,尾指针指向这个常量数组最后一个元素的后面,其内部只含有两个指针,因此大小为8
那类似与vector和map这种容器的{}初始化是怎么实现的那
在c++11中,map和vector等这类容器中都含有initializer的构造方法,因此可以直接调用
自定义类型则直接调用自己实现的构造函数
