我想通过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>());
}

10-07 23:18