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

pmr*_*pmr 17 c++ initializer-list c++11

std::initializer_list 由编译器从大括号括起的init列表构造,并且该列表的大小必须是编译时常量.

那么为什么委员会决定从模板参数中省略大小呢?这可能会阻止一些优化并使一些事情变得不可能(std::array从a 初始化std::initializer_list).

Nic*_*las 14

如果initializer_list被定义为std::initializer_list<type, size>,则任何采用a的函数initializer_list<type>,其中type某些具体类型,现在必须是基于该列表大小的模板函数.或者他们必须要求用户传递initializer_list特定类型和大小.

这两个都是非常不可接受的.不是每个人都将所有代码都写为模板.

您可以std::array从braced-init-list 初始化a ({}中间有东西).但这与a不同std::intiializer_list.所述array类是一个聚合类型.它是一个包含单个元素的结构,它是一个公共数组.因此,在符合C++ 11的实现上,这应该编译:

std::array<int, 3> myArray = {1, 3, 5};
Run Code Online (Sandbox Code Playgroud)

但是,{1, 3, 5}不是一个std::initializer_list对象; 它只是一个braced-init-list,可用于初始化适当的类型.

您不能将std::initializer_list对象传递给aggegate的构造函数(因为聚合没有构造函数),但是您可以使用braced-init-list来调用聚合初始化来初始化a std::array,就像对包含数组的任何结构一样.

a std::initializer_list和braced-init-list之间的区别有点像an int和literal 之间的区别0.将int对象隐式转换为指针类型并不(通常)合法,但将整数文字0隐式转换为指针类型是合法的.braced-init-lists的工作方式是这样的:

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
Run Code Online (Sandbox Code Playgroud)

  • @Nicol:它们的目的是为了编写一个`make_array`函数,就像在SO上多次出现一样.在任何情况下,我发现说"*你可以从初始化列表*初始化`std :: array`"是错误的,当你真正的意思是`std :: array`可以用表面上类似的语法初始化. (4认同)
  • @ildjarn:这就是为什么语句后面跟着"排序"并且没有提到`std :: initializer_list`的类型,而只是"初始化列表".注意缺少下划线. (2认同)

Pup*_*ppy 7

现有系统的一个优点是您可以导出initializer_list从DLL 获取的函数.如果按尺寸模板化,则必须将它们作为来源运输.

  • 沿着同样的路线:它可能会导致一些非平凡的膨胀. (4认同)