2011-03-30 54 views
0

我生病了手工書寫的構造函數。我如何自動執行此操作?基於非靜態數據成員自動生成構造函數?

struct MyFunctor { 
public: 
    MyFunctor(/* repeat what I wrote again!*/) 
    :/* repeat what I wrote again! */ 
    { } 

    bool operator()() { return true; } 

private: 
    Controller *m_controller; 
    String m_action; 
    bool m_allowRejection; 
    /* ... */ 
}; 
+0

你的意思是你想接受成員的類型和直接初始化? – GManNickG 2011-03-30 06:28:14

+0

你想讓參數列表具有'Controller * a_controller,String a_action,bool a_allowRejection'嗎?一個富有魅力的宏偉宏觀工作? – 2011-03-30 06:28:22

+0

@詹姆斯甚至編輯插件凱特會工作:) – 2011-03-30 06:38:38

回答

1

像這樣的宏可以使用的,但它可以說是醜陋:

#include <boost/preprocessor.hpp> 

#define AUTO_CONSTRUCTOR_DETAIL_PARAM(r, data, member) \ 
     BOOST_TYPEOF(member) member 

#define AUTO_CONSTRUCTOR_DETAIL_INIT(r, data, member) \ 
     member(member) 

#define AUTO_CONSTRUCTOR_DETAIL(className, mems) \ 
     className(BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_TRANSFORM(\ 
        AUTO_CONSTRUCTOR_DETAIL_PARAM, BOOST_PP_EMPTY, members))) : \ 
     BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_TRANSFORM(\ 
      AUTO_CONSTRUCTOR_DETAIL_INIT, BOOST_PP_EMPTY, member)) \ 
     {} 

#define AUTO_CONSTRUCTOR(className, members) \ 
     AUTO_CONSTRUCTOR_DETAIL(className, members) 

用途爲:

struct MyFunctor { 
public: 
    AUTO_CONSTRUCTOR(MyFunctor, (m_controller)(m_action)(m_allowRejection)) 

    bool operator()() { return true; } 

private: 
    Controller *m_controller; 
    String m_action; 
    bool m_allowRejection; 
    /* ... */ 
}; 

未經檢驗的,當然。

+0

我不認爲'BOOST_TYPEOF(member)'是有效的。這對於非靜態數據成員來說不是一個有效的表達式: – 2011-03-30 07:41:37

+0

@Johannes:你認爲'BOOST_TYPEOF(((data *)0) - > member)'會起作用,那麼?(其中'data'是'className'。) – GManNickG 2011-03-30 07:56:40

3

你可以放棄數據隱藏和利用好舊結構的初始化從C:

struct MyFunctor 
{ 
    Controller *m_controller; 
    String m_action; 
    bool m_allowRejection; 

    bool operator()() const 
    { 
     return true; 
    } 
}; 

MyFunctor fun = {&some_controller, "hello world", false}; 

在C++ 0x中,你甚至可以創建對象的即時得益於統一初始化:

some_function(MyFunctor {&some_controller, "hello world", false}); 

...或者你可以切換到Scala和使用主要構造;)

+0

當類繼承另一個類時(這個類變成非集合:() – 2011-03-30 15:31:40

0

呃... ... GMAN的回答讓我以爲除上葉宏:

#define FOR_EACH_FIELD(macro) \ 
    macro(Controller*, m_controller) \ 
    macro(String, m_action) \ 
    macro(bool, m_allowRejection) 

然後濫用有增加零碎格式化......我要試試其他的宏宏觀,但它很容易成爲......亂七八糟無論如何我的猜測這是不值得的。最終用途是這樣的:

struct MyFunctor { 
#define FOR_EACH_FIELD(macro) // as above 
    CREATE_CONSTRUCTOR(MyFunctor, FOR_EACH_FIELD) // this macro will call others. 
    bool operator()() {} 
private: 
    CREATE_FIELDS(FOR_EACH_FIELD); 
#undef FOR_EACH_FIELD 
}; 
0

如果你只需要值初始化,您可以使用一個模板描述here - 整齊,你不要重複自己。

0

我不知道有一個簡單的答案:在某些時候,你必須告訴 編譯器什麼的初始化值。然而,對於某些頻繁使用的 模式,您可能可以編寫一個簡單的代碼生成器: 您可以在輸入時提供一個包含三列列表的文件:名稱,類型和默認初始化程序,編譯器將生成默認構造函數 ,初始化構造函數和數據。 (這將是 簡單的延伸,以允許更多的功能。)

0

如果你使用這個純粹作爲類的存儲類型,你可以使用Boost::tuple,它會自動生成這樣一個構造函數,所以您的類看起來是這樣的:

tuple<Controller, String, bool> MyFunctor; 

這裏的問題是,它不提供任何的方式爲您包括您operator()。不幸的是,由於構建函數是不能繼承的,你可以不通過試圖創建一個使用functor_baseboost::tuple,然後推導是添加你的operator()類一事無成。

明顯的替代將是改寫tuple允許您指定各成員函數的代碼。我不確定如何做到這一點 - 但這需要仔細考慮(最好)。

相關問題