c++ - 如何通过 C++ 标准类型特征切换传递的值?

标签 c++ c++11 templates typetraits

我想通过 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/

相关文章:

c++ - 如何打印 C++11 时间点?

c++ - 寻找最小楼梯成本的动态规划问题的错误答案

c++ - 将 std::list<>::iterator 的值指向指针?

c# - 运行托管代码的非托管线程

c++ - 混合 libstdc++ 版本

c++ - 为什么不能构造包含 ostringstream 成员的对象?

函数模板的 C++ 问题(未找到实例)

c++ - 在 C++ 中为 vector 查找函数

c++ - 如何将 lambda、函数对象或 std::function 作为模板参数传递并控制它们的参数

c++ - sclite (SCTK),C++ 模板参数 Filter::Filter* 无效。 Cygwin