Это возможный использовать повышение:: связать для эффективной конкатенации функций?

Предположите, что у меня есть повышение:: функция с произвольной подписью назвала тип 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;
}
6
задан Catskul 30 April 2010 в 01:24
поделиться

2 ответа

Boost уже предоставляет способ создания последовательности связанных функций. Используйте оператор запятой лямбды .

using namespace boost::lambda;
MyClass mc;
CallbackType object = (bind(&MyClass::alert, mc), bind(doIt, _1, _2, _3));
object(1, 2, 3);

Это создаст новый функтор, объект . Когда вы вызываете этот функтор с тремя аргументами, он, в свою очередь, вызывает mc.alert () перед передачей этих аргументов в doIt . Скобки важны.

Чтобы мой пример работал, вам нужно, чтобы alert был функцией const . Если он должен быть неконстантным, то либо передайте указатель в mc , либо оберните его с помощью boost :: ref (mc) . И вам нужно будет использовать Boost.Lambda bind , а не Boost.Bind; последний несовместим с операторами объединения функций Lambda (в частности, с запятой).

8
ответ дан 10 December 2019 в 02:44
поделиться
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 использует много препроцессорного взлома для своего вариативного вуду, и, к сожалению, я не думаю, что он предоставляет шаблон или инструменты для исправления ошибок, которые, по сути, являются тем, чем это является.

1
ответ дан 10 December 2019 в 02:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: