5

簡単に修正できる問題が発生していますが、途方に暮れています...

次のコードを実行するテンプレートがあります。

T value     = d;
if ( std::numeric_limits< T >::is_signed )
{
    if ( value < 0 )
    {
        *this += _T( "-" );
        value = -(signed)value;
    }
}

明らかな理由で、このコードが符号なし型用にコンパイルされると、GCCは警告を出します(データ型の範囲が限られているため、比較は常にfalseです)。私はこの背後にある理由を完全に理解しており、numeric_limitsチェックを入れて、コンパイラーにシャットダウンさせることができるかどうかを確認しました(MSVCでは機能しました)。悲しいかな、GCCの下で私は警告を受けます。この警告を修正する方法はありますか(GCCで実行できるかどうかさえわかりませんが、警告を無効にする以外に)ありますか?とにかくコードが呼び出されることはなく、オプティマイザーもコードをコンパイルすると思いますが、警告を取り除くことはできません。

誰かが私にこれに対する解決策を与えることができますか?

乾杯!

4

4 に答える 4

5

より簡単な解決策:

template <typename T> inline bool isNegative(T value) {
  return std::numeric_limits< T >::is_signed && value < 0; // Doesn't trigger warning.
}

T value     = d;
if ( isNegative(value) ) // Doesn't trigger warning either.
{
    *this += _T( "-" );
    value = -1 * value;
}
于 2010-06-29T12:18:32.757 に答える
3

誰かが私にこれに対する解決策を与えることができますか?

革命的なことは何もありませんが、私は通常、オーバーロードによってこれを行います。それらの線に沿った何か:

//Beware, brain-compiled code ahead!
template< bool B >
struct Bool { const static bool result = B; }

template< typename T >
void do_it(T& , Bool<false> /*is_signed*/)
{
  // nothing to do for unsigned types
}

template< typename T >
void do_it(T& value, Bool<true> /*is_signed*/)
{
    if ( value < 0 ) {
        *this += _T( "-" );
        value = -(signed)value;
    }
}

template< typename T >
void do_something(T& value)
{
  do_it(value, Bool<std::numeric_limits< T >::is_signed>() );
}

関数テンプレートの代わりにクラステンプレートを使用できる場合は、オーバーロードの代わりに特殊化を使用できます。(関数テンプレートの部分的な特殊化はありません。これにより、関数テンプレートの特殊化が少し面倒になります。)

于 2010-06-29T11:14:06.240 に答える
3

-Wtype-limits警告をケースバイケースで抑制できる実際のソリューションについては、https: //stackoverflow.com/a/8658004/274937を参照してください。つまり、警告を生成する各比較をダミー関数にラップするだけです。

于 2011-12-28T16:03:46.790 に答える
2

次のように関数を特殊化できます。

template <bool S> 
void manipulate_sign(T&) {}

template <> 
void manipulate_sign<true>(T& value) {
  if ( value < 0 )
  {
    *this += _T( "-" );
    value = -(signed)value;
  }
}

//then call like this:
manipulate_sign<std::numeric_limits< T >::is_signed>();

ただし、警告を無効にするだけの方がよい場合があります。

于 2010-06-29T11:15:13.350 に答える