std::initializer_list
由编译器从大括号括起来的init列表构造而成,并且此列表的大小必须是编译时间常量。为什么大小不是std :: initializer_list的模板参数?
那么为什么委员会决定从模板参数中省略大小呢?这可能会阻止某些优化并使某些事情不可行(从std::initializer_list
初始化std::array
)。
std::initializer_list
由编译器从大括号括起来的init列表构造而成,并且此列表的大小必须是编译时间常量。为什么大小不是std :: initializer_list的模板参数?
那么为什么委员会决定从模板参数中省略大小呢?这可能会阻止某些优化并使某些事情不可行(从std::initializer_list
初始化std::array
)。
现有系统的一个优点是可以导出从DLL中取出initializer_list
的函数。如果它是根据尺寸模板化的,则必须将其作为源代码进行发货。
沿着同样的路线:它可能会导致一些不平凡的膨胀。 – MSalters
如果initializer_list
被定义为std::initializer_list<type, size>
,然后任何函数,它的initializer_list<type>
,其中type
是一些具体的类型,现在就必须根据该列表的大小的模板功能。或者他们将不得不要求用户通过的特定类型的initializer_list
并且尺寸为。
这两个都是非常不可接受的。并非所有人都将他们的代码编写为模板。
您可以从braced-init-list({}
中间的东西)初始化一个std::array
。但这与std::intiializer_list
不一样。 array
类是一个聚合类型。它是一个包含单个元素的结构,它是一个公共数组。因此,在一个符合C++ 11个实施方式中,这应该编译:
std::array<int, 3> myArray = {1, 3, 5};
然而,{1, 3, 5}
不是std::initializer_list
对象;它只是一个braced-init-list,可以用来初始化适当的类型。
您不能std::initializer_list
对象传递给aggegate的构造函数(因为聚集有没有构造函数),但你可以使用一个支撑,初始化列表来调用集合初始化,初始化std::array
,就像你对任何结构包含一个数组。
std::initializer_list
与加载初始化列表之间的区别有点像int
和字面0
之间的区别。将(int
)对象隐式转换为指针类型并不是(通常)合法的,但将整数文字0隐式转换为指针类型是合法的。方式支撑-INIT-名单的工作是这样的:
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
一个非常类似的问题是: “为什么'的std :: initializer_list :: size'不'constexpr'(了)?”这是一年前在clC++ m上提出的。 – MSalters
Re MSalters'2011评论,请注意,即使C++ 11没有,C++ 14 *也会使std :: initializer_list :: size成为'constexpr'函数。 http://en.cppreference.com/w/cpp/utility/initializer_list/size – Quuxplusone