2011-02-09 18 views
3

:しかしC4333(「>>」:あまりにも大きな量だけ右シフト、データの損失)警告回避する方法私は、バッファに任意のサイズの整数に変換するには、以下の機能を持っている

template<typename T> 
std::string build_data_from(T val) 
{ 
    std::string result; 

    for (int i = 0; i < sizeof(val); i++) 
    { 
    result.insert(0, 1, char(val)); 
    val = val >> 8; 
    } 

    return result; 
}; 

を、呼び出しをunsigned char型とテンプレート関数は、Visual C++ 2008で警告をレンダリング:

std::string x(build_data_from<unsigned char>(1)); 

警告C4333: '>>': 大きすぎた分だけ右シフト、データ損失

それを回避するために(プラグマ警告ディレクティブを使用せずに)任意のクリーンな方法はありますか?

+1

にあなたはunsigned char型のケースのためのテンプレート関数を特化できます。しかしこれはダブルコード化が必要な回避策に過ぎません。 –

+0

bitshift関数だけを抽出して特殊化することもできます。 – UncleBens

+0

@king_nak:実際にはダブルコーディングではなく、 'char'と' unsigned char'に必要なループ/ビットシフトがなく、メソッドがはるかに簡単です。 –

答えて

2

かなり簡単です:unsigned char(およびchar)の場合はbuild_data_fromです。

これは、それが簡単になるだろうと私はプレーンなオーバーロードをお勧めする、プレーンな過負荷またはstd::enable_ifのいずれかを使用して行うことができます。

std::string build_data_from(char val) 
{ 
    std::string result; result += val; return result; 
} 

std::string build_data_from(unsigned char val) 
{ 
    return build_data_from(char(val)); 
} 

しかし、あなたはcharunsigned charをキャストすることを意識していますいくつかの奇妙な出力を生成する可能性がありますか? (私はunsigned charは実際に印刷可能でない値があるかもしれないということを意味する)

2

あなたは、単一のif -statementでこの問題を回避することができます:条件付きif (sizeof(T) > 1)は任意のための一定なのでTコンパイラが最適化されます

template<typename T> 
std::string build_data_from(T val) 
{ 
    std::string result; 

    for (size_t i = 0; i < sizeof(val); i++) 
    { 
    result.insert(0, 1, char(val)); 
    if (sizeof (T) > 1) 
     val = val >> 8; 
    } 

    return result; 
} 

それは実行時のオーバーヘッドがなく、警告もありません。 Tcharの場合は、シフトが最適化されているため、コードが少し速くなります。

Btw:i変数をsize_tとし、intではないと宣言する必要があります。 sizeof()の結果はsize_tであり、いくつかのコンパイラ(gccなど)は、符号付き整数と符号なし整数の比較を行うと警告します。

+0

'sizeof'はビット数ではなく' char'の数を与えるので、あなたは 'sizeof(T)> 1'を意味すると思います。また、ループは 'char'と' unsigned char'のために偽です。データを追加することができるので、 'insert'を呼び出す必要はありません...もっと簡単にオーバーロードすることができます:) –

+0

もちろん.. stupid me私は答えを編集します –

+0

あなたの提案はまだ警告を表示します。私はMatthieuの解決策を受け入れました。 –

3

次のように警告します。

変更

val = val >> 8; 

val = val >> 7 >> 1; 

または

val = (val >> 7 >> 1) & 0xff; 
+0

なぜ他の解決策がより多くのアップフォートを持っていたのか分かりません...これは最もクリーンでシンプルな解決策のようです...私のために働く! –

関連する問題