18

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

2
  • 4
    A very similar question is "why is std::initializer_list::size not constexpr (anymore) ?" which was asked on clc++m a year ago. Commented Aug 18, 2011 at 14:05
  • 1
    Re MSalters' 2011 comment, notice that C++14 does make std::initializer_list::size a constexpr function, even though C++11 didn't. en.cppreference.com/w/cpp/utility/initializer_list/size Commented Jan 22, 2014 at 6:17

2 Answers 2

16

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
Sign up to request clarification or add additional context in comments.

8 Comments

Are you sure about initializing std::array from std::initializer_list? array<int, 3> x = {1,2,3} does not work on gcc 4.6 and I cannot infer that this should work from n3242.
@pmr: std::array is defined (in N3291) as a struct, and it follows the C++0x rules for an aggregate type. Therefore, it should be initialized via aggregate initialization. So you initialize it as though it were a struct holding an array of 3 elements. I'll update my post to explain this.
@Nicol : That's just aggregate initialization -- initializer_list is completely orthogonal.
@Nicol : They do for purposes of e.g. writing a make_array function, as has been brought up multiple times on SO. In any case, I find it misleading to say "You can initialize a std::array from an initializer list" when what you really mean is just that std::array can be initialized with superficially similar syntax.
@ildjarn: Which is why the statement is followed by "sort of" and doesn't mention std::initializer_list the type, but simply "an initializer list". Notice the lack of an underscore.
|
8

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.

1 Comment

Along the same lines: it can cause some non-trivial bloat.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.