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};
The general answer is no. The use of a braced-init-list as the initializer will first try to resolve to the constructor that takes an std::initializer_list
. As an illustration:
#include <iostream>
#include <vector>
int main() {
auto p = new std::vector<int>{1};
auto q = new std::vector<int>(1);
std::cout << p->at(0) << '\n';
std::cout << q->at(0) << '\n';
}
Note the semantics of list-initialization (Quoted from cppreference):
- All constructors that take std::initializer_list as the only argument, or as the first argument if the remaining arguments have default values, are examined, and matched by overload resolution against a single argument of type std::initializer_list
- 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. If this stage produces an explicit constructor as the best match for a copy-list-initialization, compilation fails (note, in simple copy-initialization, explicit constructors are not considered at all)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With