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?
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;
}