std :: numeric_limits作为条件

时间:2014-08-11 19:59:28

标签: c++ templates c++11 numeric-limits

我是否可以使用std::numeric_limits<T>::is_integerstd::numeric_limits<T>::is_specialized来更改模板行为?

例如,我可以这样做:

template < typename T >
void foo( const T& bar )
{
    if( std::numeric_limits< T >::is_integer )
    {
        isInt( bar );
    }
    else if( std::numeric_limits< T >::is_specialized )
    {
        isFloat( bar );
    }
    else
    {
        isString( bar );
    }
}

2 个答案:

答案 0 :(得分:8)

您拥有的内容目前有效。但是,您应该更喜欢使用SFINAE和<type_traits>,因为它会根据类型调度到不同的函数,而不是依赖于分支条件(可能会或可能不会被优化掉)。

您可以使用std::enable_if执行以下操作:

template<typename T, 
         typename std::enable_if<std::is_integral<T>::value, int>::type = 0>
void foo(const T& t) {
    isInt(t);
}

template<typename T, 
         typename std::enable_if<std::is_floating_point<T>::value, int>::type = 0>
void foo(const T& t) {
    isFloat(t);
}

template<typename T, 
         typename std::enable_if<!std::is_integral<T>::value && 
                                 !std::is_floating_point<T>::value, int>::type = 0>
void foo(const T& t) {
    isString(t);
}

Live Demo

enable_if的第二个参数设置为int的原因是为我们节省了一些输入。如果遗漏了int,那么我们必须typename = typename std::enable_if<std::is_integral<T>::value>::type而不是将其设置为0,这样可以节省几个字符的输入。它们等同于所有意图和目的。

答案 1 :(得分:4)

“显而易见”的答案是你可以使用像std::enable_if这样的东西。

例如:

template<typename T>
typename std::enable_if<std::numeric_limits<T>::is_integer, void>::type
    foo(const T &bar) { isInt(bar); }
template<typename T>
typename std::enable_if<std::numeric_limits<T>::is_specialized, void>::type
    foo(const T &bar) { isFloat(bar); }

这种方法的问题在于,int numeric_limits参数(例如)numeric_limits<int>::is_specialized == true,这是不明确的。

要解决这个问题,我个人会使用比template<typename T> typename std::enable_if<std::numeric_limits<T>::is_specialized && !std::numeric_limits<T>::is_integer, void>::type foo(const T &bar) { isFloat(bar); } 更好的特性。您还可以使用布尔条件来测试所需的确切条件:

{{1}}