简体   繁体   English

为什么大小不是std :: initializer_list的模板参数?

[英]Why is the size not a template argument of std::initializer_list?

std::initializer_list is constructed by the compiler from a brace-enclosed init list and the size of this list must be a compile time constant. std::initializer_list由编译器从一个用大括号括起来的init列表构造,并且此列表的大小必须是编译时间常数。

So why did the committee decide to omit the size from the template arguments? 那么,委员会为什么决定忽略模板参数的大小呢? This possibly prevents some optimizations and makes some things impossible (initializing std::array from a std::initializer_list ). 这可能会阻止一些优化并使某些事情变得不可能(从std::initializer_list初始化std::array )。

If initializer_list was defined as std::initializer_list<type, size> , then any function that takes an initializer_list<type> , where type is some concrete type, would now have to be a template function based on that list's size. 如果initializer_list定义为std::initializer_list<type, size> ,则任何采用initializer_list<type>type是某种具体类型)的函数现在都必须是基于列表大小的模板函数。 Or they would have to require that users pass an initializer_list of a specific type and size . 否则,他们将需要用户传递特定类型和大小initializer_list

Both of these are pretty unacceptable. 这两个都是不可接受的。 Not everyone writes all of their code as templates. 并非所有人都将所有代码都写为模板。

You can initialize a std::array from a braced-init-list ( {} with stuff in the middle). 您可以从括号初始化列表( {} ,中间有东西)初始化std::array But that's not the same thing as a std::intiializer_list . 但这与std::intiializer_list The array class is an aggregate type. array类是聚合类型。 It is a struct that contains a single element, which is a public array. 它是一个包含单个元素的结构,该元素是一个公共数组。 Therefore, on a conforming C++11 implementations, this should compile: 因此,在符合标准的C ++ 11实现中,应编译为:

std::array<int, 3> myArray = {1, 3, 5};

However, {1, 3, 5} is not a std::initializer_list object; 但是, {1, 3, 5}不是std::initializer_list对象; it is merely a braced-init-list, which can be used to initialize appropriate types. 它只是一个braced-init-list,可用于初始化适当的类型。

You cannot pass a std::initializer_list object to the constructor of an aggegate (because aggregates have no constructors), but you can use a braced-init-list to invoke aggregate initialization to initialize a std::array , just as you would for any struct containing an array. 您不能将std::initializer_list对象传递给aggegate的构造函数(因为集合没有构造函数),但是您可以使用braced-init-list调用集合初始化来初始化std::array ,就像对包含数组的任何结构。

The difference between a std::initializer_list and a braced-init-list is a bit like the difference between an int and the literal 0 . std::initializer_list和braced-init-list之间的区别有点像int和立即数0之间的区别。 It's not (usually) legal to implicitly convert an int object into a pointer type, but it is legal to implicitly convert an integer literal 0 into a pointer type. (通常)将int对象隐式转换为指针类型是不合法的,但是将整数常量0隐式转换为指针类型是合法的。 The way braced-init-lists work is like that: 括号初始化列表的工作方式如下:

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. 现有系统的一个好处是,您可以导出从DLL中获取initializer_list函数。 If it were templated on the size, they would have to be shipped as source. 如果按大小模板化,则必须将它们作为源发货。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM