Я сейчас пишу в системе обработчиков событий на C ++ 0x. «Обработчики» для каждого события (может быть несколько обработчиков) регистрируются путем передачи любого вида функции / метода, которые могут быть сохранены в объекте std::function
. Это делается в стиле C # с использованием перегруженного оператора + =. Мой Event-Class выглядит в основном так (раздет для лучшей читаемости):
template<typename THandlerReturn, typename THandlerArgs...>
class Event {
public:
typedef THandlerReturn(HandlerSignature)(THandlerArgs...);
typedef THandlerReturn(*HandlerFuntionPtr)(THandlerArgs...);
typedef typename std::function<HandlerSignature> HandlerFunction;
void operator += (HandlerFunction handler) {
_handlers.push_back(handler);
}
// Some other methods for calling all handlers, ctors, etc.
private:
std::vector<HandlerFunction> _handlers;
};
Теперь у меня есть другой внутренний метод для извлечения фактического указателя на функцию из std::function
объектов, хранящихся в векторе. В основном он пытается сделать что-то вроде этого:
// Preceeding: Get an iterator 'it' from the vector
HandlerFunctionPtr pt2func = it->target<HandlerSignature>();
В этот момент, когда я использую класс Event в своем приложении, компиляция завершится неудачно. Используя сборку GCC 4.7, я получаю следующие сообщения об ошибках для строки выше:
error: expected primary-expression before '>' token
error: expected primary-expression before ')' token
Я немного протестировал метод target<>()
, и следующее прекрасно работает, предполагая, что тип возвращаемого значения void
и есть один аргумент типа int
:
typedef void(Signature)(int);
typedef void(*FunctionPtr)(int);
std::function<Signature> func;
FunctionPtr pt2func = func.target<Signature>();
Но как только включается один аргумент шаблона, я получаю опубликованные выше ошибки:
typedef THandlerReturn(Signature)(int);
typedef THandlerReturn(*FunctionPtr)(void);
std::function<Signature> func;
FunctionPtr pt2func = func.target<Signature>();
Может кто-нибудь сказать мне, почему это на самом деле, и если да, есть ли способ заставить это работать? Любая помощь и идеи очень ценятся! Заранее спасибо!