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

しかし、gcc4.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 をそれぞれサポートしている場合は、または名前空間でenable_ifおよびを見つけることができます。それ以外の場合、Boost には型特性ライブラリBoost.TypeTraitsの実装があります。のブースト実装は少し異なります。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 に答える
1
于 2015-07-06T08:26:41.820 に答える
0

unsigned次のようなタイプの特別なテンプレート関数の実装を実装できます。

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

UPDATE 符号なしフラグ

使用したいすべての符号なしタイプに対して異なる実装を実装するか、次の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 に答える