I want to switch passed value through C++ standard type trait. Here is the test code show what I mean:
template<typename T>
T _func(T t, std::is_integral<T>||std::is_enum<T>)
{
return t;
}
template<typename T>
T _func(T t, std::is_floating_point<T>)
{
return t;
}
template<typename T>
T _func(T t, std::is_same<T, std::string>)
{
return t;
}
template<typename T>
T func(T t)
{
return _func(t, T)
}
It doesn't work of course. I try my best to test and find a way to implement this:
int testint(int t){ return t;}
std::string testString(std::string t ){return t;}
float testreal(float t ){return t;}
template <typename T>
T test_string_type(T t, std::true_type) {
return testString(t);
}
template <typename T>
T test_string_type(T t, std::false_type) {
return t;
}
template<typename T>
T test_real_type(T t, std::true_type)
{
return testreal(t) ;
}
template<typename T>
T test_real_type(T t, std::false_type)
{
return test_string_type(t, std::is_same<T, std::string>());
}
template<typename T>
T test_enum_type(T t, std::true_type)
{
return testint(t) ;
}
template<typename T>
T test_enum_type(T t, std::false_type)
{
return test_real_type(t, std::is_floating_point<T>());
}
template<typename T>
T test_integer_type(T t, std::true_type)
{
return testint(t) ;
}
template<typename T>
T test_integer_type(T t, std::false_type)
{
return test_enum_type(t, std::is_enum<T>()) ;
}
template<typename T>
T test(T t)
{
return test_integer_type(t, std::is_integral<T>());
}
It works, but really ugly code. Is there any kind of smart way to solve this?
You can use SFINAE to reject overloads
or use tag dispatching similar to what you've shown, but handle the alternatives differently to reduce the number of cases