使用std::make_shared初始化带有std::array参数的std::shared_ptr

3

我不理解为什么这个可以正常工作:

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;
    };
};


1
什么是MyClass? - Oblivion
1
它的构造函数是什么样子的? - Ted Lyngmo
2个回答

5

花括号初始化{}在模板上下文中不能被推导为类型。特例是auto,其被推导为std::initializer_list。您始终需要明确定义类型。

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

2
auto myobj = std::make_shared<MyClass>(std::array{0., 1.}); 这样写也可以。 - Ted Lyngmo

-1

{0, 0}的类型取决于上下文。如果{0, 0}被用于立即构建另一个已知类型的对象,则表示该对象类型的prvalue

MyClass m({0, 0}); 

这里的{0, 0}指的是类型为std::array<double, 2>的prvalue。 另一方面,如果对类型没有限制,那么{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


这是不正确的。当使用auto时,{0, 0}只是一个std::initializer_list<int>。没有它就没有类型 - NathanOliver
当传递给模板函数时,它不也是std :: initializer_list吗? - Alecto Irene Perez
没有为模板推导设置规则,但是为了让auto能够工作,添加了一个特殊规则(仍然不确定是否喜欢这个规则)。 - NathanOliver

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接