I asked a question here: Lifetime Extension of a initializer_list return involving the non-functional code:
const auto foo = [](const auto& a, const auto& b, const auto& c) { return {a, b, c}; };
I believed the lambda was trying to return an intializer_list
(that's bad, don't do that.) But I got a comment:
It's not an
initializer_list
, it's an initializer list. Two different things.
I just thought that any time you did a curly-braced list you were creating an intializer_list
. If that's not what's happening, what is a list in curly-braces?
A compound statement is a sequence of zero or more statements enclosed within curly braces. Compound statements are frequently used in selection and loop statements.
Definition of curly brace : either one of the marks { or } that are used as a pair around words or items that are to be considered together.
An open curly bracket is { and a close curly bracket is } Curly brackets are used to mark what code is in a certain block. To type a curly bracket, hold down the SHIFT key and press the key that has [ and { on it. You can find that key on your keyboard directly to the right of P.
Without curly brackets, you could accidentally write a semicolon after the IF-statements. The semicolon is a valid, empty statement, which will be "execute" instead of the actual (intended) one.
It is an braced-init-list. A braced-init-list existed before std::initializer_list
and is used to initialize aggregates.
int arr[] = {1,2,3,4,5};
The above used a braced-init-list to initialize the array, no std::initializer_list
is created. On the other hand when you do
std::vector<int> foo = {1,2,3,4,5};
foo
is not an aggregate so the braced-init-list is used to create a std::initializer_list
which is in turned passed to the constructor of foo
that accepts a std::initializer_list
.
A thing to note about a braced-init-list is that is has no type so special rules were developed for use with it and auto
. It has the following behavior (since the adoption of N3922)
auto x1 = { 1, 2 }; // decltype(x1) is std::initializer_list<int> auto x2 = { 1, 2.0 }; // error: cannot deduce element type auto x3{ 1, 2 }; // error: not a single element auto x4 = { 3 }; // decltype(x4) is std::initializer_list<int> auto x5{ 3 }; // decltype(x5) is int
And you can get more information on history of this behavior and why it was changed at: Why does auto x{3} deduce an initializer_list?
There are three distinct, but related concepts here:
braced-init-list: The grammatical rule associated with curly-brace-enclosed lists in certain contexts.
Initializer list: The name for the braced-init-list initializer used in list-initialization.
std::initializer_list
: A class wrapping a temporary array which is created in some contexts involving braced-init-lists.
Some examples:
//a braced-init-list and initializer list, //but doesn't create a std::initializer_list int a {4}; //a braced-init-list and initializer list, //creates a std::initializer_list std::vector b {1, 2, 3}; //a braced-init-list and initializer list, //does not create a std::initializer_list (aggregate initialization) int c[] = {1, 2, 3}; //d is a std::initializer_list created from an initializer list std::initializer_list d {1, 2, 3}; //e is std::initializer_list<int> auto e = { 4 }; //f used to be a std::initializer_list<int>, but is now int after N3922 auto f { 4 };
You might want to read N3922, which changed some of the rules involving auto
and std::initializer_list
.
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