Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
331 views
in Technique[技术] by (71.8m points)

c++ - 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.

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).

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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. Or they would have to require that users pass an initializer_list of a specific type and size.

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). But that's not the same thing as a std::intiializer_list. The array class is an aggregate type. It is a struct that contains a single element, which is a public array. Therefore, on a conforming C++11 implementations, this should compile:

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

However, {1, 3, 5} is not a std::initializer_list object; it is merely a braced-init-list, which can be used to initialize appropriate types.

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.

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. 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. 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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...