2017-04-21 95 views
3

我有一個是這樣的代碼:可變參數模板擴張,繼承和std ::的unique_ptr

#include <memory> 
#include <vector> 

using namespace std; 

struct A { 
    virtual ~A() = default; 
}; 

struct B : public A { 
}; 

template<typename... Ts> struct C { 
    C() : v_({new Ts...}) {} 

    ... 

    std::vector<A*> v_; 
}; 

... 

C<B, B, A> bba; 

我想使用std::unique_ptrstd::make_unique避免調用new明確並遍歷v_將其刪除在破壞者(v_將成爲std::vector<std::unique_ptr<A>>),但無法弄清楚如何結婚std::make_unique與初始化列表和可變擴展(我懷疑由於std::unique_ptr是移動只)。有什麼建議麼?

+0

它改變了問題,但爲什麼'std :: vector >'而不是說'std :: tuple ...>'?如果預期集合會更改內容簽名,則構造函數應該是模板,而不是類。 – TBBle

回答

3

怎麼樣C構造函數如下?

// C++11 version (std::make_unique() unavailable in C++11) 
    C() 
    { 
     using unused = int[]; 

     v_.reserve(sizeof...(Ts)); 

     (void)unused { 0, (v_.emplace_back(new Ts), 0)... }; 
    } 

    // C++14 version 
    C() 
    { 
     using unused = int[]; 

     v_.reserve(sizeof...(Ts)); 

     (void)unused { 0, (v_.emplace_back(std::make_unique<Ts>()), 0)... }; 
    } 

初始0unused(建議從aschepler(謝謝!))准許

C<> etl; 

的定義與C空類型列表。

+0

我會給'u'增加一個額外的0,以便'C <>'起作用。爲什麼在C++ 11中不能使用「C++ 14版本」? – aschepler

+0

@aschepler - 好主意多餘的0,我會用它;第二個解決方案是C++ 14,因爲(如果我記得正確)'std :: make_unique()'是一個(從C++ 14開始的)特性。 – max66