What is the difference between C c(3); and C c{3}; when instantiating a class?

Viewed 93
#include <iostream>

using namespace std;

class C{
    public: int a;
    public: C (int i){a = i ; }

};
int main()
{
    C c(3); // C c{3};
    cout<<c.a;
    return 0;
}

What is the difference between C c(3); and C c{3};? They seem to work the same as invoking the constructor.

2 Answers

There are two differences:

  1. The brace-initialization syntax (assuming the list is nonempty) can call an std::initializer_list<T> constructor, and will always do so if possible. The parenthesis syntax will not call an std::initializer_list<T> constructor.

  2. The brace-initialization syntax prohibits narrowing conversions.

In your example there is no difference, but:

  1. If C had a constructor taking std::initializer_list<int> then C{3} would call that constructor while C(3) would call the one that takes int.

  2. C{3.14} will not compile since the conversion is narrowing, but C(3.14) will.

The effect is same for this case.

C c(3); is direct intialization,

the constructors of T are examined and the best match is selected by overload resolution. The constructor is then called to initialize the object.

C c{3}; is direct-list-initialization (since C++11),

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.

So for both cases C::C(int) is used for initializing the object.


Depending on the behavior of C, the other potential differences between C c(3); and C c{3}; include:

Related