У меня есть класс с функцией «Прикрепить», которая принимает объект функции и сохраняет его в коллекции. Сам класс затенен на подпись функции. Что-то вроде этого:Templating boost :: bind для автоматической обработки нескольких аргументов для функции-члена
template<class Signature>
class Event
{
public:
void Attach(boost::function<Signature> signature)
{
MySignatures.push_back(signature);
}
private:
std::list<boost::function<Signature>> MySignatures;
};
Чтобы продемонстрировать использование, рассмотрим следующий класс:
class Listening
{
public:
int SomeFunction(int x, int y, int z);
};
Чтобы передать функцию на Listening
в Event
, я должен был бы написать:
Event<int(int, int, int)> myEvent;
Listening myListening;
myEvent.Attach(boost::bind(boost::mem_fn(&Listening::SomeFunction), &myListening, _1, _2, _3));
Так вместо этого для каждого случая, который может быть подвержен ошибкам, я пишу набор макросов следующим образом:
#define EventArgument0(x, y) boost::bind(boost::mem_fn(x), y)
#define EventArgument1(x, y) boost::bind(boost::mem_fn(x), y, _1)
#define EventArgument2(x, y) boost::bind(boost::mem_fn(x), y, _1, _2)
#define EventArgument3(x, y) boost::bind(boost::mem_fn(x), y, _1, _2, _3)
#define EventArgument4(x, y) boost::bind(boost::mem_fn(x), y, _1, _2, _3, _4)
etc.
и тогда я могу написать:
myEvent.Attach(EventArgument3(&Listening::SomeFunction, &myListening));
, который намного легче читать (я думаю). Теперь мой вопрос: как я могу вместо этого написать:
myEvent.Attach(EventArgument(&Listening::SomeFunction, &MyListening));
или даже лучше:
myEvent.Attach(&Listening::SomeFunction, &myListening);
, так что событие Приложить волшебно связать правильно с соответствующим количеством аргументов, содержащихся в < Подпись > (в этом примере, int(int, int, int)
)? Я открыт для любого шаблона мета-программирования, который вы имеете в виду здесь.
Спасибо.
Edit: оказывается, мне не нужно boost::mem_fn
здесь, потому что boost::bind
эквивалентно, поэтому в моем макрос можно использовать:
bind(&MyClass::Hello, myClass, _1, _2, _3);
, вместо:
bind(mem_fn(&MyClass::Hello), myClass, _1, _2, _3);
Вопрос остается: как передать &MyClass::Hello
классу событий и использовать перегрузку шаблона для обработки _1
, _2
, _3
и т. д., подразумеваемых прототипом функции, используемой для шаблона Event
класс?
Вы пытались использовать Google/Bing для «идеальной пересылки»? Предположим, вы можете использовать C++ 0x. – Henrik
Я сейчас смотрю на это, например здесь: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2002/n1385.htm. Мне непонятно, как это помогает решить проблему. – Robinson