用大括号赋值和调用构造函数一样吗?

Is assign with braces the same as call the constructor?

我知道对于标量类型你可以用大括号赋值,比如 int a { 0 };.

这有助于转换,类型转换 ecc。

但是udt呢?是

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

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

大括号应该调用构造函数吧?

它像初始化列表吗?

我知道 std::initializer_list 是什么,但它必须是同一类型 T,而在 { my_alloc(42), my_free } 中,类型不同。

这是direct list initialization

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

这是第一种语法的示例:

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

因此它的确切效果是

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)

有关实际含义的更多详细信息:

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 没有采用 std::initializer_list 的构造函数,因此第二个要点适用,它是根据其中的参数构造的。