Hi all,
I am exploring C++11 templates with Microsoft's VS2013. Recently I came across the following problem:
* I have a template function with a dummy function body.
* I want to create a specialization that works for all suitable types, e.g. all integer types, all floating-point types, or all character types.
Let me give you a simple example. The function Invert should return the bit-inverted parameter value, which of course makes no sense for most data types, so the dummy implementation returns 0:
template<typename T> T Invert(T data)
{ return T();
}
Now I can start to specialize the template:
template<> int Invert(int data)
{ return ~data;
}
template<> unsigned Invert(unsigned data)
{ return ~data;
}
for all suitable data types: char, int, short, long, long long, in their signed and unsigned variants. That creates multiplied code. So I thought there must be a better solution, and my guess is that SFINAE is the answer.
I created a template class in type_traits style
template<typename T> struct IsSuitableType
{
static bool const value = std::is_integral<T>::value && !std::is_enum<T>::value && !std::is_same<T, bool>::value;
};
to make expressions shorter, and then wrote "generic" specialization:
template<typename T> std::enable_if_t<IsSuitableType<T>::value, T> Invert(T data)
{ return ~data;
}
but compiling test code where Invert<int> is called gives me
error C2668: 'Invert' : ambiguous call to overloaded function
could be 'int Invert<int>(T)'
or 'T Invert<int>(T)'
(For illustration, the test code is simply: int i = Invert(3);)
This only works if I modify the original template definition so that I now have
template<typename T> std::enable_if_t<!IsSuitableType<T>::value, T> Invert(T data)
{ return T();
}
template<typename T> std::enable_if_t<IsSuitableType<T>::value, T> Invert(T data)
{ return ~data;
}
which makes the dummy function less generic, and I would have to modify the template every time I add some new specialization, which is not how (in my understanding) template programming should be done.
How can I solve this problem?