std::initializer_list
由编译器从大括号括起来的初始化列表中构造,并且该列表的大小必须是编译时常量。
那么为什么委员会决定从模板参数中省略大小呢?这可能会阻止一些优化并使某些事情变得不可能(std::array
从 a初始化std::initializer_list
)。
std::initializer_list
由编译器从大括号括起来的初始化列表中构造,并且该列表的大小必须是编译时常量。
那么为什么委员会决定从模板参数中省略大小呢?这可能会阻止一些优化并使某些事情变得不可能(std::array
从 a初始化std::initializer_list
)。
如果initializer_list
定义为std::initializer_list<type, size>
,那么任何采用 的函数initializer_list<type>
(其中type
是某种具体类型)现在都必须是基于该列表大小的模板函数。或者他们必须要求用户传递initializer_list
一个特定类型和大小的。
这两个都是非常不可接受的。不是每个人都将他们所有的代码都写成模板。
您可以std::array
从一个花括号初始化列表初始化 a ({}
中间有东西)。但这与std::intiializer_list
. 该类array
是一个聚合类型。它是一个包含单个元素的结构,它是一个公共数组。因此,在符合 C++11 的实现上,它应该编译:
std::array<int, 3> myArray = {1, 3, 5};
然而,{1, 3, 5}
不是一个std::initializer_list
对象;它只是一个花括号初始化列表,可用于初始化适当的类型。
您不能将std::initializer_list
对象传递给聚合的构造函数(因为聚合没有构造函数),但您可以使用花括号初始化列表来调用聚合初始化来初始化 a std::array
,就像对任何包含数组的结构一样。
astd::initializer_list
和 braced-init-list 之间的区别有点像 anint
和 literal之间的区别0
。将对象隐式转换为指针类型(通常)是不合法的int
,但将整数文字 0 隐式转换为指针类型是合法的。支撑初始化列表的工作方式是这样的:
int i = 0; //Legal
void *j = 0; //Legal
void *k = i; //Not legal
std::array<int, 3> myArray = {1, 3, 5}; //Legal
std::initializer_list<int> myInitList = {1, 3, 5}; //Legal
std::array<int, 3> myArray = myInitList; //Not legal
One upside of the existing system is that you can export functions which take an initializer_list
from a DLL. If it were templated on the size, they would have to be shipped as source.