22

鉴于:

template<typename T>
inline bool f( T n ) {
  return n >= 0 && n <= 100;
}   

unsigned类型一起使用时会产生警告:

unsigned n;
f( n ); // warning: comparison n >= 0 is always true

n >= 0有没有什么聪明的方法不做类型的T比较unsigned?我尝试添加部分模板专业化:

template<typename T>
inline bool f( unsigned T n ) {
  return n <= 100;
}   

但 gcc 4.2.1 不喜欢这样。(无论如何,我不认为这种部分模板专业化是合法的。)

4

5 回答 5

24

您可以使用enable_if类型is_unsigned特征:

template <typename T>
typename std::enable_if<std::is_unsigned<T>::value, bool>::type f(T n)
{
    return n <= 100;  
}

template <typename T>
typename std::enable_if<!std::is_unsigned<T>::value, bool>::type f(T n)
{
    return n >= 0 && n <= 100;  
}

如果您的编译器分别支持 C++0x 或 TR1,您可以在or命名空间中找到enable_ifand 。否则,Boost 具有类型特征库Boost.TypeTraits的实现。boost 的实现有点不同;类似于 TR1 和 C++0x 。is_unsignedstdstd::tr1enable_ifboost::enable_if_cenable_if

于 2011-01-21T18:01:28.770 回答
16

您可以利用无符号整数的环绕行为。

template<bool> struct bool_ { };

template<typename T>
inline bool f( T n, bool_<false> ) {
  return n >= 0 && n <= 100;
}

template<typename T>
inline bool f( T n, bool_<true> ) {
  return n <= 100;
}

template<typename T>
inline bool f( T n ) {
  return f(n, bool_<(static_cast<T>(-1) > 0)>());
}   

重要的是不要说>= 0,以避免再次警告。以下似乎也欺骗了 GCC

template<typename T>
inline bool f( T n ) {
  return (n == 0 || n > 0) && n <= 100;
}   
于 2011-01-21T17:59:11.653 回答
6
于 2018-10-12T20:40:49.523 回答
1
于 2015-07-06T08:26:41.820 回答
0

您可以为以下类型实现特殊的模板函数实现unsigned

template<class T> bool f(T val);
template<> bool f<unsigned>(unsigned val);

更新无符号标志

您可以为您想要使用的所有无符号类型实现不同的实现,或者添加一个bool标志,例如:

template <class T, bool U> bool f(T val)
{
        if (U)
                return val <= 100;
        else
                return (val >=0 ) && (val <= 100);
}

...

cout << f<int, false>(1) << endl;
cout << f<int, false>(-1) << endl;
cout << f<char, true>(10) << endl;
于 2011-01-21T17:59:21.177 回答