6

假设我有一个 boost::function ,带有一个名为 type 的任意签名CallbackType

  • 是否可以使用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;
}
4

2 回答 2

8

Boost 已经提供了一种创建绑定函数序列的方法。使用Lambda 的逗号运算符

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函数。如果它需要是非常量的,那么要么传递一个指向 的指针mc要么用boost::ref(mc). 您需要使用 Boost.Lambdabind而不是 Boost.Bind;后者与 Lambda 的函数组合运算符(尤其是逗号)不兼容。

于 2010-05-14T17:52:20.880 回答
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 对其可变参数巫毒术使用了大量的预处理器黑客攻击,不幸的是,我认为它没有提供用于头部修补的模式或工具,本质上就是这样。

于 2010-04-30T06:30:17.317 回答