std::enable_if fails to specialize class template while is able to specialize function template

21 Views Asked by At

Suppose I have a family of enums with predefined structure:

enum class A {BEGIN, a, b, c, END};

Now I need to implement a way to get min and max values (somewhat like numeric limits) which is able to work with both standard numeric types and enums.

If I write something like following chunk of code, I get desired result:

template <typename T, typename std::enable_if_t<std::is_enum_v<T>, bool> = true>
T min() {
    return T::BEGIN;
}

template <typename T, typename std::enable_if_t<!std::is_enum_v<T>, bool> = true>
T min() {
    return std::numeric_limits<T>::min();
}
...

min<A>(); // works

But shall I try to structure it a bit more, I immidiatelly get template redefinition errors:

template <typename T, typename std::enable_if_t<!std::is_enum_v<T>, bool> = true>
struct NumericLimits{
    static T min() { return std::numeric_limits<T>::min(); }
    static T max() { return std::numeric_limits<T>::max(); }
};

template <typename T, typename std::enable_if_t<std::is_enum_v<T>, bool> = true>
struct NumericLimits {
    static T min() { return T::BEGIN; }
    static T max() { return T::END; }
};
...
NumericLimits<A>::min(); // error
 

Compiler complais of following on call:

<source>:60:74: error: template non-type parameter has a different type 'typename std::enable_if_t<std::is_enum_v<T>, bool>' (aka 'typename enable_if<std::is_enum_v<T>, bool>::type') in template redeclaration
template <typename T, typename std::enable_if_t<std::is_enum_v<T>, bool> = true>

Although I kind of have what I want with the fist approach, I'm wondering what's wrong with second? I'd expect it to work too. Why am I unable to specialize class template? Or why function template specialization is not treated as redeclaration?

0

There are 0 best solutions below