以下是扩展版本,工作正常,我只想使用初始化列表
vector<shared_ptr<Foo>> inputs = {
make_shared<Foo>("foo"),
make_shared<Foo>("bar"),
make_shared<Foo>("baz")
};
所以我尝试过像
这样的事情vector<shared_ptr<Foo>> inputs2 = {
{ "foo" },
{ "bar" },
{ "baz" }
};
以及两个括号,或者没有括号,即{{ "foo" }}
和"foo"
。
std::shared_ptr<Foo> foo = { "foo" };
也没有编译,所以我认为这根本不是向量问题,而是用初始化列表初始化shared_ptrs。
答案 0 :(得分:4)
唯一合理的版本是您建议的第一个版本 如果查看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
做的是使用T*
构建它,所以这应该有效:
std::shared_ptr<std::string> p(new std::string("hi"));
现在,您可能会想“嘿!我可以在初始化列表中使用它!”但是,不,这个:
std::initializer_list<std::shared_ptr<std::string>> il{
new std::string("hi there"),
new std::string("hi there")
};
不起作用, 因为该特定的构造函数在其上具有显式关键字,所以必须明确声明它!
所以最终,你可以写一些像
这样的东西std::initializer_list<std::shared_ptr<std::string>> il{
std::shared_ptr<std::string>(new std::string("hi there"))
};
但正如您所见,您的第一次尝试更简单,更短。
summery:鉴于没有将参数传递给manged对象构造函数的shared_ptr构造函数,您无法真正使用{args ...}作为有效语法。鉴于必须明确声明获得T*
的shared_ptr,你不能像{new T(args ..)}那样做,所以最简单的方法是使用std::make_shared
。
PS。在你的第一个片段中,用于初始化向量的东西是初始化列表。只有它的类型是std::initializer_list<std::shared_ptr<Foo>>
而不是std::initializer_list<Foo>
,就像第二个片段一样。
答案 1 :(得分:1)
你可以这样做一些愚蠢的事情:
template< typename Cont >
void consume_append_shared( Cont& c ) {} // terminator
template< typename Cont, typename T, typename... Args >
void consume_append_shared( Cont& c, T&& t, Args&& ...args )
{
typedef typename Cont::value_type::element_type ElemType;
c.push_back(
std::make_shared<ElemType> ( std::forward<T>(t) )
);
consume_append_shared( c, std::forward<Args>(args)... );
}
template<typename T, typename... Args>
std::vector< std::shared_ptr<T> > make_shared_vector( Args&& ...args )
{
std::vector< std::shared_ptr<T> > vec;
vec.reserve( sizeof...(Args) );
consume_append_shared( vec, std::forward<Args>(args)... );
return vec;
}
直播here
只有在T&#39的构造函数需要一个参数时才有效。