7

What's the difference between () and {} when constructing objects?

I think {} should only support with initializer_list or an array, but when I run below snip, I confused.

#include <iostream>
using namespace std;
struct S {
    int v=0;
    S(int l) : v(l) {
    }
};


int main()
{
    S s1(12); // statement1
    S s2{12}; // statement2
    cout << s1.v << endl;
    cout << s2.v << endl;
}

statement1 is right because () is the basic grammar for constructing the object.

I expect the statement2 will be compiled failed. I think {} is only can be used for an array or initializer_list type. but the actual result is compiled perfectly without error.

what do I mis?

Guokas
  • 750
  • 7
  • 23
  • 1
    you miss uniform initialization, if you never heard about it you should search for it, it was a big thing in c++11 – 463035818_is_not_an_ai Aug 01 '19 at 08:34
  • 1
    And I personally recommend to avoid it: `std::vector v{10, 12}` – what do you think it will produce? With `std::vector v(10, 12)` and `std::vector v({10, 12})` everything just more clear... – Aconcagua Aug 01 '19 at 08:58

1 Answers1

8

For S, they have the same effect. Both invoke the constructor S::S(int) to initialize the objects.

S s2{12}; is regared as list initialization (since C++11); S is not an aggregate type and not std::initializer_list, and has no constructor taking std::initializer_list, then

If the previous stage does not produce a match, all constructors of T participate in overload resolution against the set of arguments that consists of the elements of the braced-init-list, with the restriction that only non-narrowing conversions are allowed.

and you thought that

I think {} is only can be used for an array or initializer_list type.

This is not true. The effect of list-initialization is that, e.g. if S is an aggregate type, then aggregate initialization is performed; if S is a specialization of std::initializer_list, then it's initialized as a std::initializer_list; if S has a constructor taking std::initializer_list, then it will be preferred to be used for initialization. You can refer to the page linked for more precise details.

PS: S s1(12); performs direct initialization.

songyuanyao
  • 169,198
  • 16
  • 310
  • 405