Предположите, что у меня есть повышение:: функция с произвольной подписью назвала тип 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;
}
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 (в частности, с запятой).
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 использует много препроцессорного взлома для своего вариативного вуду, и, к сожалению, я не думаю, что он предоставляет шаблон или инструменты для исправления ошибок, которые, по сути, являются тем, чем это является.