У меня есть класс с функцией «Attach», который принимает объект функции и сохраняет его в коллекции.Сам класс основан на сигнатуре функции.Примерно так:
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);
, чтобы событие Attach волшебным образом связывалось с соответствующим количеством аргументов каксодержится в (в этом примере int(int, int, int)
)?Я открыт для любой магии метапрограммирования шаблонов, которую вы здесь имеете в виду.
Спасибо.
Редактировать: оказывается, мне здесь не нужно 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
?