我厌倦了手动编写构造函数。我该如何实现自动化?
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 :(得分: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
允许您指定各种成员函数的代码。我不知道如何做到这一点 - 需要仔细考虑(充其量)。