使用 std::make_shared 初始化 std::shared_ptr 并以 std::array 作为参数

Initializing std::shared_ptr with std::make_shared having an std::array as argument

我不明白为什么这样可以正常工作:

std::array<double, 2> someArray = {0,1};
std::shared_ptr<MyClass> myobj = std::make_shared<MyClass>(someArray);

但这不起作用:

std::shared_ptr<MyClass> myobj = std::make_shared<MyClass>({0,1});

编译器说:

too many arguments to function ‘std::shared_ptr< _Tp> std::make_shared(_Args&& ...)
...
candidate expects 1 argument, 0 provided

问题:有人可以解释为什么会发生这种情况吗?如果有任何方法可以在不定义额外变量的情况下修复第二种方法?


编辑: MyClass 示例:

#include <memory> //For std::shared_ptr
#include <array>
#include <iostream>

class MyClass{
  public:
    MyClass(std::array<double, 2> ){
      std::cout << "hi" << std::endl;
    };
};

大括号初始值设定项{} 永远无法推导为类型(在模板上下文中)。一个特例是 auto,它被推导为 std::initializer_list。您始终必须明确定义类型。

auto myobj = std::make_shared<MyClass>(std::array<double, 2>{0, 1});

{0, 0} 的类型取决于上下文。如果 {0, 0} 被用于立即构造另一个已知类型的对象,那么它代表该对象类型的 prvalue

MyClass m({0, 0}); 

这里,{0, 0}指的是std::array<double, 2>类型的纯右值 另一方面,如果类型没有限制,那么 {0, 0} 指的是 std::initializer_list<int>:

类型的初始化列表
auto vals = {0, 0};

无法从 std::initializer_list<int> 初始化 MyClass,因此 make_shared 编译失败:

MyClass m(vals); // Fails: can't construct MyClass from initializer list

这如何连接到 std::make_shared 因为 std::make_shared 是一个模板,所以 {0, 0} 没有被用来构建特定的类型。因此,它被视为 std::initializer_list