唯一合理的版本是您建议的第一个版本。
如果你看看std::shared_ptr documentation,你会发现没有构造函数将托管对象构造函数参数作为可变参数模板。这意味着你不会找到像财产以后:
template<class T,class... Arg>
std::shared_ptr<T>::shared_ptr(Args&&... args)
所以你不能真正做财产以后像
std::shared_ptr<std::string> p("hi there");
将无法正常工作。现在
std::shared_ptr<std::string> p(new std::string("hi"));
,你可能会想: 你能为std::shared_ptr
做什么用T*
构建它,所以这应该工作,“嘿,我可以用它的初始化列表里面!”但是,不,这:
std::initializer_list<std::shared_ptr<std::string>> il{
new std::string("hi there"),
new std::string("hi there")
};
将无法正常工作,因为 特定costructor上有明确的关键字,因此必须显式声明!
所以最后,你可以写类似
std::initializer_list<std::shared_ptr<std::string>> il{
std::shared_ptr<std::string>(new std::string("hi there"))
};
但正如你看到你自己,你的第一次尝试是简单得多和更短。
summery:由于没有将参数传递给管理对象构造函数的shared_ptr构造函数,因此不能真正将{args ...}用作有效语法。考虑到必须明确声明T*
的shared_ptr这一事实,你不能做像{new T(args ..)}这样的事情,所以最简单的方法是使用std::make_shared
。
ps。在你的第一个片段中,用于初始化向量的东西是初始化器列表。只是它的类型是std::initializer_list<std::shared_ptr<Foo>>
,而不是像第二个片段那样的std::initializer_list<Foo>
。