I have a large template definition (large as it overloads most of the operators) with which I have a problem when I need to specialize it for bool.
There is one example, although all the comparison operators are affected:
template<class T, T min, T max, T init_value = static_cast<T>(0)>
class limited_auto_enum_init
{
...snip...
bool operator == (T v) const { return f_value == v; }
bool operator == (bool v) const { return f_value == v; }
...snip...
};
As the name of the class implies, you are expected to make use of it when T comes from an enumeration. Since bool
is generally viewed as an enumeration, I also want to instantiate a specialization for the bool
type:
typedef limited_auto_enum_init<bool, false, true, false> flbool_t;
typedef limited_auto_enum_init<bool, false, true, true> tlbool_t;
When I do that, T
is bool
and therefore both functions have the exact same signature.
I looked into SFINAE and came up with something like this:
template<class = typename std::enable_if<!std::is_fundamental<T>::value>::type>
bool operator == (T v) const { return f_value == v; }
But for bool
that tells me:
error: no type named ‘type’ in ‘struct std::enable_if’
For user enumerations it works fine.
Update:
I found a solution that works for me, as pointed out by @jrok (although the answer marked as the solution did not help me at all!). I had to define the return type of the other operator (the one explicitly taking a bool):
template<class Q = T>
typename std::enable_if<!std::is_fundamental<Q>::value, Q>::type
operator == (bool v) const { return f_value == v; }
That way the compiler (g++) is happy and fails as expected.