基于非静态数据成员自动生成构造函数?

时间:2011-03-30 06:24:29

标签: c++ dry functor

我厌倦了手动编写构造函数。我该如何实现自动化?

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;
  /* ... */
};

6 个答案:

答案 0 :(得分:3)

您可以放弃数据隐藏并使用C:

中的旧的struct初始化
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并使用主构造函数;)

答案 1 :(得分: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;
  /* ... */
};

当然没有经过测试。

答案 2 :(得分: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
};

答案 3 :(得分:0)

如果你只需要进行价值初始化,你可以使用here描述的模板 - 整洁,你不要重复自己。

答案 4 :(得分:0)

我不确定是否有一个简单的答案:在某些时候,你必须告诉我 编译器初始化值是什么。对于一定的频繁 但是,您可以编写一个简单的代码生成器: 您将在条目中提供一个包含三列列表的文件:名称,类型和 默认初始化程序,编译器将生成默认值 构造函数,初始构造函数和数据。 (这将是 简单扩展以允许其他功能。)

答案 5 :(得分:0)

如果您纯粹将其用作类的存储类型,则可以使用Boost::tuple,它会自动生成这样的ctor,因此您的类看起来像:

tuple<Controller, String, bool> MyFunctor;

问题在于它没有为您提供任何方式来包含operator()。不幸的是,由于ctors不是继承的,你可以通过尝试使用functor_base创建boost::tuple来完成任何事情,然后派生一个添加了operator()的类

显而易见的替代方法是重写tuple允许您指定各种成员函数的代码。我不知道如何做到这一点 - 需要仔细考虑(充其量)。