template<typename T, typename std::enable_if<std::is_enum<T>::value>::type* = nullptr>
void show_value(T x)
не более специализирован, чем (поймать все)
template<class T> void show_value(T x);
, поэтому вызов с enum
неоднозначен.
Вы должны либо отказаться от универсального c один для non enum:
template<typename T, typename std::enable_if<!std::is_enum<T>::value>::type* = nullptr>
void show_value(T x) { std::cout << "Obj.text: " << x.text << std::endl; };
или предоставление им приоритета.
struct low_priority_overload {};
struct high_priority_overload : low_priority_overload{};
// Or use template <std::size_t N> struct priority_overload : priority_overload<N - 1>{}
template<typename T, typename std::enable_if<std::is_enum<T>::value>::type* = nullptr>
void show_value_impl(high_priority_overload, T x) { cout<<"Enum: "<<(int)x<<endl; };
void show_value_impl(high_priority_overload, int x) { cout<<"Int: "<<x<<endl; };
void show_value_impl(high_priority_overload, string x) { cout<<"String: "<<x<<endl; };
template<class T>
void show_value_impl(low_priority_overload, T x) { cout<<"Obj.text: "<<x.text<<endl; };
template<class T>
void show_value(T x)
{
show_value_impl(high_priority_overload{}, x);
}