的std :: numeric_limits作为条件(std::numeric_limits as

2019-10-20 16:39发布

有没有我可以用一种方式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 );
    }
}

Answer 1:

该“显而易见”的答案是,你可以使用类似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<int>::is_specialized == true

要解决这个问题,我会简单地使用比更好的特点numeric_limits ,个人。 您还可以使用布尔条件来测试你想要的确切条件:

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); }


Answer 2:

你有什么是当前有效的。 然而,你应该更喜欢使用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);
}

现场演示

对于第二个参数的原因enable_if设置为int是我们节省一些打字。 如果int留出那么我们要做的typename = typename std::enable_if<std::is_integral<T>::value>::type的只是将其设置为而不是0这将几个字符救我们类型。 他们是等效的所有意图和目的。



文章来源: std::numeric_limits as a Condition