基于整数类型"signed-ness"的部分模板专业化?

Pau*_*cas 21 c++ templates specialization

鉴于:

template<typename T>
inline bool f( T n ) {
  return n >= 0 && n <= 100;
}   
Run Code Online (Sandbox Code Playgroud)

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

unsigned n;
f( n ); // warning: comparison n >= 0 is always true
Run Code Online (Sandbox Code Playgroud)

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

template<typename T>
inline bool f( unsigned T n ) {
  return n <= 100;
}   
Run Code Online (Sandbox Code Playgroud)

但是gcc 4.2.1并不喜欢这样.(我没想到的是一种模板偏特的将是法律反正.)

Jam*_*lis 24

你可以用enable_ifis_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;  
}
Run Code Online (Sandbox Code Playgroud)

你可以找到enable_ifis_unsignedstdstd::tr1命名空间,如果你的编译器支持分别C++ 0x或TR1.否则,Boost有一个类型特征库Boost.TypeTraits的实现.推动实施enable_if有点不同; boost::enable_if_c类似于TR1和C++ 0x enable_if.


Joh*_*itb 15

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

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)>());
}   
Run Code Online (Sandbox Code Playgroud)

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

template<typename T>
inline bool f( T n ) {
  return (n == 0 || n > 0) && n <= 100;
}   
Run Code Online (Sandbox Code Playgroud)


Nat*_*ica 9

开始,if constexpr您甚至不需要为此提供专业化。与普通的 if 语句不同,如果表达式if constexpr不为 true,则 if 语句中的代码将被丢弃(不编译)。这意味着你可以像这样重写你的函数

template<typename T>
inline bool f( T n ) 
{
    if constexpr (std::is_unsigned_v<T>)
        return n <= 100;
    else
        return n >= 0 && n <= 100;
}   
Run Code Online (Sandbox Code Playgroud)