I have a template function where an enum type is converted to its underlying type which works fine, but I wrote an overload which should take an integral number and return itself and it give me an error that int is not an enumeration type. In my template, this should have been filtered out. What is wrong?
Here is the template code:
template <typename TT>
static constexpr auto get_value(TT t)
-> typename std::enable_if<!std::is_enum<TT>::value, TT>::type
{
return t;
}
template <typename TT>
static constexpr auto get_value(TT t)
-> typename std::enable_if<std::is_enum<TT>::value, typename std::underlying_type<TT>::type>::type
{
return (typename std::underlying_type<TT>::type)t;
}
underlying_type
is SFINAE-friendly, but there's a workaround for that – Citoleunderlying_type
by SFINAE friendly? – Brehmstd::underlying_type<TT>::type
is deferred, so thatenable_if
can fail first. By SFINAE-friendly I mean that any substitution failure happens only in immediate context (if it happens insideunderlying_type
itself it's not SFINAE-friendly). – Citoletemplate<class T> struct B : T {}; template<class T> B<T> foo();
thenfoo<int>
will not produce a substitution failure in the immediate context (the base class itself could inherit from other classes, where finally an deeply nested error occurs). – Noblesse