2015-10-05 25 views
1

以下是扩展版本,它工作得很好,只是我想使用初始化列表如何初始化具有一个参数的类的shared_ptr向量?

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与初始化列表。

回答

3

唯一合理的版本是您建议的第一个版本。
如果你看看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>

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的构造函数期待一个参数的功能。