2011-03-30 56 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允许您指定各成员函数的代码。我不确定如何做到这一点 - 但这需要仔细考虑(最好)。

相关问题