我想通过 C++ 标准类型特征切换传递的值。这是测试代码,说明我的意思:
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)
}
当然不行。我尽力测试并找到实现此方法的方法:
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>());
}
它可以工作,但是代码真的很丑。 有什么聪明的方法可以解决这个问题吗?
最佳答案
您可以使用 SFINAE拒绝重载
template<typename T>
typename std::enable_if<std::is_integral<T>::value || std::is_enum<T>::value>::type
func(T t)
{
return t;
}
template<typename T>
typename std::enable_if<std::is_floating_point<T>::value>::type
func(T t)
{
return t;
}
template<typename T>
typename std::enable_if<std::is_same<T, std::string>::value>::type
func(T t)
{
return t;
}
或使用与您所展示的类似的标签分派(dispatch),但以不同方式处理备选方案以减少案例数量
namespace detail
{
template<typename T>
T func(T t, std::false_type /*is_string*/, std::false_type /*is_float*/, std::true_type /*is_int*/)
{
return t;
}
template<typename T>
T func(T t, std::false_type /*is_string*/, std::true_type /*is_float*/, std::false_type /*is_int*/)
{
return t;
}
template<typename T>
T func(T t, std::true_type /*is_string*/, std::false_type /*is_float*/, std::false_type /*is_int*/)
{
return t;
}
}
template<typename T>
T func(T t)
{
return detail::func(t, std::is_same<string, T>(),
std::is_floating_point<T>(),
std::integral_constant<bool, std::is_integral<T>::value || std::is_enum<T>::value>());
}
关于c++ - 如何通过 C++ 标准类型特征切换传递的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41372896/