I have a class template:
template <typename Argument> class Signal
{
void invoke(Argument arg) {}
};
Now I want to invoke signals without parameter (meaning void
parameter). I assume I could specialize the whole class for void
and it would compile. But there's a lot of code in the class, I don't want to duplicate it. I want to only specialize whatever neccessary. So I try adding:
// void specialization
template<>
void Signal<void>::invoke()
{
}
And get an error:
error C2244: 'Signal::invoke' : unable to match function definition to an existing declaration
Why is that?
The same code works for any type other than void
.
If yo will try to declare a variable
you also will receive a compile error.
The problem is that compiler expects some type instead of Argument here
and void is not treated as a type here.
What about C++11 variadic templates :
It scales well with 0, 1 or more args.
The specialization for this template:
would be:
which is illegal because you can't have a void object.
One way of doing what you want is to use overloading to declare both invoke methods, and use some templating tricks (I believe this one is called SFINAE) to only allow the correct overload available based on your class template argument:
You can find more about the usage of
enable_if
here: std::enable_if to conditionally compile a member function, Why should I avoid std::enable_if in function signatures.