2016-05-12 26 views
2

我有一個模板類Container與定義模板的構造函數的默認constructible類如下:有條件構建一個參數包

template<class... Objects> 
class Container 
{ 
public: 
    template<class... Objs> 
    Container(Objs*... objs) 
    { 
     // initialize all pointers of m_objs to nullptr 
     objs_init<Objects...>(); 

     // initialize the pointers of m_objs corresponding to parameters pack objs... 
     objs_init<Objs...>(objs...); 
    } 

private: 
    template<class Obj, class O1, class ...On> 
    void objs_init() 
    { 
     objs_init<Obj>(); 
     objs_init<O1, On...>(); 
    } 
    template<class Obj, class O1, class ...On> 
    void objs_init(Obj* obj, O1* o1, On*... on) 
    { 
     objs_init<Obj>(obj); 
     objs_init<O1, On...>(o1, on...); 
    } 
    template<class Obj> 
    void objs_init(Obj* obj = nullptr) 
    { 
     std::get<Obj*>(m_objs) = obj; 
    } 

    std::tuple<Objects*...>  m_objs; 
}; 

和一些類ABC,...定義如下:

class A { public: A(bool) {} }; 
class B { /*trivial default ctor*/ }; 
class C { public: C(int) {} }; 

如果我創建一個Container<A,B,C>對象是這樣的:

Container<A,B,C> cnt(new A(true), new C(1)); 

假設模板參數指定的所有課程都不同,Container<>模板的構造函數按預期工作,即:

  • m_objs元組的所有指針是否第一套nullptr,然後
  • 1日(A* )和第三個(C*)指針m_objs分別設置爲由new A(true)new C(1)返回的值。

現在,我想Container<>構造函數默認構造每個未初始化的指針m_objs。但我不知道如何實現這一點。

我嘗試添加下面的模板成員函數Container<>

template<class Obj, class O1, class ...On> 
    void objs_ctor() 
    { 
     objs_ctor<Obj>(); 
     objs_ctor<O1, On...>(); 
    } 
    template<class Obj> 
    void objs_ctor() 
    { 
     Obj*& obj = std::get<Obj*>(m_objs); 
     if (obj == nullptr) 
      obj = new Obj; 
    } 

Container<>構造函數objs_ctor<>呼叫:

 // default-construct unitialized pointers of `m_objs` 
     objs_ctor<Objects...>();    

然而,這顯然是行不通的,因爲我的方式來實現objs_ctor<>要求默認構造函數存在每個參數包的類(我不想);所以我得到以下編譯器錯誤:

error C2512: 'A' : no appropriate default constructor available 

爲了這個工作,我也需要檢查,如果我嘗試自動創建該對象是默認構造的。我認爲這可以使用std::is_default_constructible<>來實現,但我不知道如何正確使用它。

感謝您的幫助。

回答

2

假設。

通話添加到objs_ctors<Objects...>();在構造

template<class... Objs> 
    Container(Objs*... objs) 
     { 
     objs_init<Objects...>(); 
     objs_init<Objs...>(objs...); 
     objs_ctors<Objects...>(); 
     } 

,並定義objs_ctor<>()objs_ctors<>()這樣

template <typename Obj> 
    typename std::enable_if<true == std::is_default_constructible<Obj>::value, void>::type objs_ctor() 
     { 
     Obj * & obj = std::get<Obj*>(m_objs); 

     if (obj == nullptr) 
      obj = new Obj; 
     } 

    template <typename Obj> 
    typename std::enable_if<false == std::is_default_constructible<Obj>::value, void>::type objs_ctor() 
     { } 

    template <typename Obj, typename O1, typename ... On> 
    void objs_ctors() 
     { 
     objs_ctor<Obj>(); 
     objs_ctors<O1, On...>(); 
     } 

    template <typename Obj> 
    void objs_ctors() 
     { 
     objs_ctor<Obj>(); 
     } 

注意,請:我想你的榜樣

Obj*& obj = std::get<Obj*>(m_objs); 
    if (obj != nullptr) 
     obj = new Obj; 

是錯誤的。

我想你的目的是修改(分配)objobjnullptr,所以

Obj*& obj = std::get<Obj*>(m_objs); 
    if (obj == nullptr) 
     obj = new Obj; 

P.S:對不起,我的英語不好。

+0

你應該好了。編輯的問題。 – shrike

相關問題