There has already been a similar question on SO, but I want to stress another aspect of braced-init-lists. Consider the following:
auto x = {1}; //(1)
This is ill-formed (8.5.4/2) unless the header <initializer_list>
is included. But why? The standard says, that the template std::initializer_list
is not predefined. Does this mean, that declaration (1) introduces a new type? In all other situations, where auto
may be used such as
auto y = expr;
where expr
is an expression, the type auto deduces already exists. On the other hand, from a logical point of view, the compiler must assign an implicite type to the construct {1}
, for which std::initializer_list
is then another name. But in declaration (1) we do not want to name this type. So why must this header be included. There is a similar situation with nullptr
. Its type implicitely exists, but to name it explicitely you have to include <cstddef>
.
An object of type std::initializer_list<T> is a lightweight proxy object that provides access to an array of objects of type const T .
std::initializer_list initializer_list objects are automatically constructed as if an array of elements of type T was allocated, with each of the elements in the list being copy-initialized to its corresponding element in the array, using any necessary non-narrowing implicit conversions.
The initializer list is used to directly initialize data members of a class. An initializer list starts after the constructor name and its parameters.
That's not the same. The rules for std::nullptr_t
and std::initializer_list
are actually different.
std::nullptr_t
is just a typedef for a built-in type. Its definition is
namespace std {
using nullptr_t = decltype(nullptr);
}
The type exists whether you include the header or not.
std::initializer_list
is a class template, not a predefined type. It really doesn't exist unless you include the header that defines it. In particular, the initializer list { 1 }
does not have type std::initializer_list<int>
; it has no type at all, because it is not an expression. (Initializer lists are special syntactic constructs and cannot appear everywhere an expression can.)
std::initializer_list
is just slightly special. For one, there are special rules for how to initialize a std::initializer_list
from the initializer list syntax (allocate an array and have the object refer to it). However, this requires std::initializer_list
to be defined in the first place.
The second special case is auto
type deduction. There's a special rule here too. But again, this doesn't mean that the compiler will automatically define the type; it just means that it will recognize it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With