2016-08-14 25 views
2

のために、私は何をすべきデクリメント付き:「署名/符号なしの不一致」の警告(C4018)C++のようなコードで、「署名/符号なしの不一致」の警告についてループ

for (int i = vector.size() - 1; i >= 0; --i) // OK 
{ 
    if (i < vector.size()/2) // warning C4018: '<': signed/unsigned mismatch 
     // ... 
} 

(不自然な例が、それ問題を示しています。)

How do I deal with "signed/unsigned mismatch" warnings (C4018)?は、ループ変数にsize_tを使用することを言いますが、これは0で終わるデクリメントループでは動作しません。これは、警告なしにコンパイルしますが、整数オーバーフロー(またはそれがアンダーフローしているのですか?)で、ランタイムになり、4294967295になります。

+0

このコードで何か問題はありません。その効果についてのあなたの理解は正しい。この警告は、コンパイラライターの意見よりも、コードの詳細を知っているときに無視できる、良いスタイルのコンパイラーライターの概念の一部です。 –

+0

@EMO:ベクトルを逆向きに反復するには、 'vector.crbegin()'を使ってみてください。 – JVApen

+1

高いWTF /分が必要な場合は、 'for(unsigned int i = vector.size() - 1; i

答えて

5

まず、あなたがunsignedタイプを使用してサイクルをデクリメント書くことができるようにしたいいくつかの十分に確立さイディオムを学びます。これは、CとC++の絶対必要不可欠なスキルです。例えば。

for ([some unsigned type] i = N; i-- > 0;) 
{ 
    // Process i-th element 
} 

または

for ([some unsigned type] i = N; i > 0;) 
{ 
    --i; 
    // Process i-th element 
} 

N - 1iの初期値がNであること、ではないに注意してください。)

それともあなたも

for ([some unsigned type] i = N - 1; i != -1; --i) 
{ 
    // Process i-th element 
} 
"より自然な" アプローチを使用することができます

第2に、vに対して適切な符号なしタイプを使用します。 ectorインデックス作成。あなたのケースでは、あなたの警告の問題を解決します

for (auto i = vector.size() - 1; i != -1; --i) 

または

for ([your vector type]::size_type i = vector.size() - 1; i != -1; --i) 

代わりに、あなたは「敗者の道を」選択することができますし、ちょうど

if ((unsigned) i < vector.size()/2) 

かだけが#pragma warning(disable: 4018)を行う明示的なキャストを使用して警告を抑制します。

0

ではなく、適切なタイプ(autostd::size_tstd::vector<...>::size_type)を使用し、(-1までvector.size() - 1からではなく)0までvector.size()から反復:

は、いくつかのオプションがあります
for (std::size_t i = vector.size(); i > 0; --i) 
{ 
    if (i < vector.size()/2 + 1) 
     // ... 
} 
+1

これを行うと、ベクトル[0] –

+0

@Dadam、noをスキップし、誰が 'vector [i-1]'ではなく、 'vector [i]'を使用するだろうと言いますか? –

+2

体験。あなたがブロックの始めに項目を参照しない限り、あなたは少なくとも1回減分を忘れてしまいます –

3

あなたができる:

ベクトルを使用する場合は、反復子を使用してそれをトラバースします:

for (auto it = vector.rbegin(); it != vector.rend(); ++it) 

または別のfor文を使用してください:

for (size_t i = vector.size(); i-- > 0;) 

また、for(size_t i = myArray.size() - 1; i != (size_t)-1; i--)(cf. What's the best way to do a backwards loop in C/C#/C++?

1

または代わり:

for(size_t j = 0; j < vector.size(); j++){ 
    size_t i = vector.size() - 1 - j; 
    ... 
} 
0

私は、アダプタのインデックス範囲を記述します。

逆方向に書き込むと、範囲を逆に反復するように調整されます。

これは私達を与える:

for(auto i:backwards(indexes_into(container))){ 

結果は(限り、あなたのユーティリティコードを信頼して)エラーが発生しにくい、などの効率的、かつ使用の時点で明確に意図しています。

両方のソリューションは、boost、rangesv3、およびさまざまなSOの投稿に存在します。

関連する問題