假设我有一个带有名为CallbackType
类型的任意签名的boost :: function。
boost::bind
组成一个函数,该函数使用与CallbackType相同的参数但连续调用两个仿函数? 我对任何可能的解决方案持开放态度,但这是......
...使用某些magic
模板的假设示例:
Template<typename CallbackType>
class MyClass
{
public:
CallbackType doBoth;
MyClass( CallbackType callback )
{
doBoth = bind( magic<CallbackType>,
protect( bind(&MyClass::alert, this) ),
protect( callback ) );
}
void alert()
{
cout << "It has been called\n";
}
};
void doIt( int a, int b, int c)
{
cout << "Doing it!" << a << b << c << "\n";
}
int main()
{
typedef boost::function<void (int, int, int)> CallbackType;
MyClass<CallbackType> object( boost::bind(doIt) );
object.doBoth();
return 0;
}
答案 0 :(得分:8)
Boost已经提供了一种创建绑定函数序列的方法。使用Lambda's comma operator。
using namespace boost::lambda;
MyClass mc;
CallbackType object = (bind(&MyClass::alert, mc), bind(doIt, _1, _2, _3));
object(1, 2, 3);
这将创建一个新的仿函数object
。当您使用三个参数调用该仿函数时,它会在将这些参数传递给mc.alert()
之前调用doIt
。括号很重要。
要使我上面的示例工作,您需要alert
成为const
函数。如果它必须是非const,则将指针传递给mc
,或用boost::ref(mc)
包装它。你需要使用Boost.Lambda的bind
而不是Boost.Bind;后者与Lambda的函数组合运算符(特别是逗号)不兼容。
答案 1 :(得分:1)
template< class Callback >
struct pre_caller {
Callback c;
pre_caller( Callback in_c ) : c( in_c ) {}
void alert() {} // or an instance of a functor
operator()
{ alert(); c(); }
template< class T1 >
operator( T1 a ) // not sure if/what qualification to add to a
{ alert(); c( a ); } // or whether to attempt to obtain from
// function_traits<Callback>?
template< class T1, class T2 >
operator( T1 a, T2 b )
{ alert(); c( a, b ); }
template< class T1, class T2, class T3 >
operator( T1 a, T2 b, T3 c )
{ alert(); c( a, b, c ); }
// ad nauseam... and I mean nausea, maybe read up on Boost Preprocessor.
};
Boost Bind使用大量的预处理器黑客来处理它的可变voodoo,不幸的是我认为它不提供头部修补的模式或工具,这实质上就是这样。