I currently write on an event handler system in C++0x. The "handlers" for each event (there can be multiple handlers) are registered by passing any kind of function/method that can be stored in a std::function
object. This is done in C# style using the overloaded += operator. My Event-Class looks basically like this (stripped for better readability):
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;
};
Now I have another internal method for retrieving the actual function pointer from the std::function
objects stored in the vector. It basically tries to do something like this:
// Preceeding: Get an iterator 'it' from the vector
HandlerFunctionPtr pt2func = it->target<HandlerSignature>();
At this point, when I 开发者_开发技巧use the Event class in my application, the compilation failes. Using a GCC 4.7 build I get the following error messages for the line above:
error: expected primary-expression before '>' token
error: expected primary-expression before ')' token
I've tested a little bit with the target<>()
Method and the following works perfectly, assuming that the return type is void
and there's one argument of type int
:
typedef void(Signature)(int);
typedef void(*FunctionPtr)(int);
std::function<Signature> func;
FunctionPtr pt2func = func.target<Signature>();
But as soon as there is one template argument involved, I get the above posted errors:
typedef THandlerReturn(Signature)(int);
typedef THandlerReturn(*FunctionPtr)(void);
std::function<Signature> func;
FunctionPtr pt2func = func.target<Signature>();
Can anyone tell me why that actually is, and if yes, if there's any way to make it work? Any help and insights are very appreciated! Thanks in advance!
You need to use template
keyword as:
HandlerFunctionPtr pt2func = it->template target<HandlerSignature>();
Its because you're calling a function template on an object whose type depends on a template argument. In the absence of the keyword template
, the compiler is going to parse your code as,
HandlerFunctionPtr pt2func = ( (it->target) < HandlerSignature ) >();
which makes absolutely no sense. Hence the error.
To know this in detail as to why template
is needed, read this excellent explanation by @Johannes Schaub:
- Where and why do I have to put the "template" and "typename" keywords?
精彩评论