Why is there not only 1 type with the best performance, to define a list at compile time?
The benchmark is clear, the constexpr std::initializer_list
is faster, uses even less memory and the IO-reads are astonishingly less over constexpr std::array
:
https://build-bench.com/b/1EDAcFjJ6NACk4Pg4tG2nbsEx0A
So why didn't they implement the array subscription methods to std::initializer_list
make std::array
unnecessary.
The question betrays some misunderstandings about what is going on here.
std::array
is an array object. It is an object whose storage size is the storage for its array elements. std::initializer_list
is a pointer to an array (one created by the compiler). You can heap-allocate std::array
for example; you cannot heap-allocate std::initializer_list
. Well, you can, but you'd just be heap allocating a pointer, which usually isn't helpful. This:
auto *p = new std::initializer_list<int>{1, 2, 3, 4};
Is broken code, as it heap allocates a pointer to an array temporary created by the compiler. An array temporary that is immediately destroyed at the end of this statement. So you now have a pointer to an array that does not exist, so using *p
or p[x]
is undefined behavior.
Doing the same with std::array
works fine, because array
is an array.
Furthermore, the purpose of std::initializer_list
is not to "define a list at compile time". As the name suggests, the point of the type is to create a list for the purpose of initializing an object. This is why the ultimate source of its data cannot be provided by any means other than a specific piece of C++ grammar, one used specifically to initialize objects: a braced-init-list.
You can use std::initializer_list
as a quick-and-dirty way of just creating an array of values for some purpose. But that's not the point of the type. That's why it doesn't have an operator[]
; because functions that can be initialized from a sequence of values don't tend to need that particular operation. They usually only need to walk it from beginning to end.