Are ={} and {}-style initializations the same in C++11?

前端 未结 3 1196
野趣味
野趣味 2021-01-02 01:05

C++11 introduced {}-style initializations. But are these two forms

T x {...};
T x = {...};

the same?

相关标签:
3条回答
  • 2021-01-02 01:17

    They are not exactly the same. Maybe this can be illustrated by a counter-example:

    struct Foo
    {
      explicit Foo(std::initializer_list<int>) {}
    };
    
    int main()
    {
      Foo f0{1, 2, 3};    // OK
      Foo f1 = {1, 2, 3}; // ERROR
    }
    

    So, the second variant requires that the type be implicitly constructable from an initialization list, whereas the first version doesn't. Note that the same applies for constructors of the form Foo(int, int, int). I chose the initializer_list<int> as an example arbitrarily.

    This would affect certain types written following the "explicit everywhere" philosophy (whereby people marked multi-parameter constructors explicit in C++03 code, even if it made no sense in that standard.)

    0 讨论(0)
  • 2021-01-02 01:18

    The syntax when using them in one case means different things

    struct A { };
    
    namespace X {
      struct A final {};
      struct A final = {};
    }
    

    In the first case, we are defining a struct called A, and in the second case we are defining an object called final.

    0 讨论(0)
  • 2021-01-02 01:24

    In addition to the difference explained in juanchopanza's answer, there is another difference, a breaking change, between direct-list-initialization and copy-list-initialization when it comes to auto and type deduction of the braced-init-list. Although it was not added as part of C++14 (last Q&A item), the issue has been identified and it is up to the committee when it will be implemented.

    For instance,

    auto foo = {42};  // deduces foo as an initializer_list<int>
    auto foo{42};     // deduces foo as an int
    

    So direct-list-initialization never deduces an initializer_list from the argument. Consequently, the following will be ill-formed.

    auto foo{1,2};    // cannot have multiple initializers for 
                      // direct-list-initialization when deducing type
    

    But this is OK:

    auto foo = {1,2}; // copy-list-initialization still deduces initializer_list<int>
    

    The same applies to generalized captures within lambda expressions. Quoting N3912

    [x{5}](){};        // x is int
    [x{1,2}](){};      // ill-formed, no multiple initializers with direct-init
    [x = {5}](){};     // ok, x is an initializer_list<int> with one element
    [x = {1,2}](){};   // ok, x is an initializer_list<int> with two elements
    
    0 讨论(0)
提交回复
热议问题