I have a template class/struct that looks like this:
template <typename T, typename U>
struct S
{
unsigned int operator()(T t, U u) const;
};
And I would like to make sure that specializations respect this interface.
Unfortunately, I can specialize this struct with a different return type. For instance if I partial-specialize to return bool
instead of unsigned int
, I would expect to get a compiler error, but the compiler does not seem to care:
template <typename T>
struct S<T,nullptr_t>
{
bool operator()(T t, nullptr_t u) const { return 2; }
};
Example @ Ideone.com
In the above example, the specialized version is supposed to return 2
but since the return type is bool
, the return value is converted to true
which is then displayed as 1
.
Why does the compiler accept this?
How can I prevent programmers from specializing the template with a wrong return type (or even with wrong arguments)?
I know I can achieve what I want with a virtual method in a base template class/struct and use the override
keyword in children:
Solution with override (does not compile, which is good)
But having a virtual method will certainly create a virtual table and I would like to avoid that as much as possible, especially since I do not need the virtual table at run-time. Unless there is a trick to do the same without building a virtual table?
Also, I know the problem would be simpler if I could partial-specialize methods or if I could rely on non-partial-specialization, but the former is not possible in C++ AFAIK and the latter does not cover the case I need in my program.