Search code examples
c++11enumstype-traits

different behaviour for enums and all other types


Using gcc-4.8 with -std=c++11 I want to create a template function with one behaviour for enums and other behaviour for all other types. I try this

#include <type_traits>
#include <iostream>

template<class T, class = typename std::enable_if<std::is_enum<T>::value>::type>
void f(T& /*t*/)
{
    std::cout << "enum" << std::endl;
}

template<class T, class = typename std::enable_if<!std::is_enum<T>::value>::type>
void f(T& /*t*/) {
    std::cout << "not enum" << std::endl;
}

enum class E
{
    A,
    B
};

int main()
{
    E e;
    f(e);
    return 0;
}

but compiler returns

1.cpp:11:6: error: redefinition of ‘template<class T, class> void f(T&)’
 void f(T& /*t*/) {
      ^
1.cpp:5:6: error: ‘template<class T, class> void f(T&)’ previously declared here
 void f(T& /*t*/)
      ^

I can comment out first template, it leads to compile error, and it's expectable. And I also can comment out second template, in this case code code can be compiled.

What do I do wrong?


Solution

  • Because compiler sees them as the same function template, instead, you should do this:

    #include <type_traits>
    #include <iostream>
    
    template<class T, typename std::enable_if<std::is_enum<T>::value, bool>::type = true>
    void f(T& /*t*/)
    {
        std::cout << "enum" << std::endl;
    }
    
    template<class T, typename std::enable_if<!std::is_enum<T>::value, bool>::type = true>
    void f(T& /*t*/) {
        std::cout << "not enum" << std::endl;
    }
    
    enum class E
    {
        A,
        B
    };
    
    int main()
    {
        E e;
        f(e);
        return 0;
    }