Search code examples
c++initializationinitializer-listinitializercurly-braces

What Is a Curly-Brace Enclosed List If Not an intializer_list?


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?


Solution

  • There are three distinct, but related concepts here:

    1. braced-init-list: The grammatical rule associated with curly-brace-enclosed lists in certain contexts.

    2. Initializer list: The name for the braced-init-list initializer used in list-initialization.

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