Home > Enterprise >  Is assign with braces the same as call the constructor?
Is assign with braces the same as call the constructor?

Time:01-07

I know that for scalar types you can assign values with braces like int a { 0 };.

This helps with cast, type conversion ecc.

But what for udt? Is

shared_ptr<int> myIntSmartPtr { my_alloc(42), my_free };

the same as

shared_ptr<int> myIntSmartPtr = shared_ptr<int>(my_alloc(42), my_free);

The braces should call the constructor, right?

Is it like an initializer list?

I know what an std::initializer_list is, but it must be the same type T, while in { my_alloc(42), my_free } the types diverge.

CodePudding user response:

This is direct list initialization.

shared_ptr<int> myIntSmartPtr { my_alloc(42), my_free };

This is an example of the first syntax:

T object { arg1, arg2, ... };   (1)

The exact effect it has is therefore

List initialization is performed in the following situations:

  • direct-list-initialization (both explicit and non-explicit constructors are considered)
    1. initialization of a named variable with a braced-init-list (that is, a possibly empty brace-enclosed list of expressions or nested braced-init-lists)

And for more detail about what that actually means:

The effects of list-initialization of an object of type T are:

... [A bunch of cases that don't apply]

Otherwise, the constructors of T are considered, in two phases:

  • 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).

std::shared_ptr does not have a constructor that takes an std::initializer_list, so the second bullet point applies and it's constructed from the arguments therein.

  •  Tags:  
  • Related