C++ Initialization – Are () and {} Always Equivalent with New Operator?

c++c++11constructorinitializationnew-operator

There is a post that deals with parentheses or not after the type name when using new. But what about this:

If 'Test' is an ordinary class, is there any difference between:

Test* test = new Test();
// and
Test* test = new Test{};

Furthermore, suppose Test2 has a constructor for an argument of type Value, is it always equivalent to write:

Value v;
Test2 *test2 = new Test(v);
// and
Test2 *test2 = new Test{v};

Best Answer

There might be difference in contexts involving std::initializer_list<>, e.g.:

Case 1 - () and {}

#include <initializer_list>
#include <iostream>
using namespace std;

struct Test2 {
    Test2(initializer_list<int> l) {}
};

int main() {
    Test2* test3 = new Test2(); // compile error: no default ctor
    Test2* test4 = new Test2{}; // calls initializer_list ctor
}

Case 2: (v) and {v}

struct Value {
};

struct Test3 {
    Test3(Value v) {}
    Test3(initializer_list<Value> v) {}
};

int main() {
    Value v;
    Test3* test5 = new Test3(v); // calls Test3(Value)
    Test3* test6 = new Test3{v}; // calls Test3(initializer_list<Value>)
}

As stated by Meyers and others there is also a huge difference when using STL:

    using Vec = std::vector<int>;
    Vec* v1 = new Vec(10); // vector of size 10 holding 10 zeroes
    Vec* v2 = new Vec{10}; // vector of size 1 holding int 10

and it is not restricted to std::vector only

In this case there's no difference though (and initializer_list ctor is ignored)

#include <initializer_list>
#include <iostream>
using namespace std;

struct Test {
    Test() {}
    Test(initializer_list<int> l) {}
};

int main() {
    Test* test1 = new Test(); // calls default ctor
    Test* test2 = new Test{}; // same, calls default ctor
}

There is also a well-known difference in this case

void f() {
    Test test{};
    Test test2();
}

where test is default-initialized object of type Test and test2 is a function declaration.

Related Question