Consider the following templated member function:
template<typename E, typename N, typename P>
void Node::connectEvent( const bool( N::*fn )( const P& ), N *inst )
{
// Obtain unique event ID based on type.
size_t eventId = typeid( E ).hash_code();
// Actual code wraps the function returned from std::bind,
// but for this example let's assume we can store it directly.
mCallbacks[eventId] = std::bind( fn, inst, std::placeholders::_1 );
}
I'd like to be able to call this function in the following way:
connectEvent<MouseDownEvent>( &MyNode::mouseDown, this );
, where the callback function is defined as:
bool MyNode::mouseDown( const MouseDownEvent &event );
, or even using a base class as parameter, which is why I have a separate event type E and parameter type P in the template:
bool MyNode::mouseDown( const Event &event );
I also need support for this:
connectEvent<DrawEvent>( &MyNode::draw, this );
, where the callback function is defined as:
bool MyNode::draw();
Question: to support the latter, I want to specialize the connectEvent
function for the case where parameter P is void, because it requires a different call to std::bind
. I've tried many different approaches, including using a combination of enable_if
and is_void
on the base template, but none compiled, so I must be doing something wrong and have resorted to trial-and-error at this point.
In most cases, the Visual Studio 2015 compiler complains about "illegal use of explicit template arguments".
Here's a version of the code that I thought would work, but didn't:
template<typename E, typename N>
void Node::connectEvent<E,N,void>( const bool( N::*fn )(void), N *inst )
{
size_t eventId = typeid( E ).hash_code();
mCallbacks[eventId] = std::bind( fn, inst );
}
What should I change in my code to make this possible?