2013-07-06 11 views
30

を、C++、私は次のコードのために署名/符号なしの不一致を警告します:ループで自動を使用すると、

auto n = a.size(); 
for (auto i = 0; i < n; i++) { 
} 

問題はiに0を割り当てることによって、それがintいうよりsize_tなることです。 だから、より良いものです:

size_t n = a.size(); 
for (size_t i = 0; i < n; i++) { 
} 

またはこの:

auto n = a.size(); 
for (size_t i = 0; i < n; i++) { 
} 

または多分あなたはよりよい解決策がありますか? もう少し一貫しているので、同じ目的のためにsize_tauto の両方ではなく、size_tを使用するだけなので、最初のものがさらに好きです。

+3

「auto i = 0u」についてはどうですか? – jalf

+0

ループでインデックスが必要な場合は、intを使用するのはどうですか?符号なしインデックスを使用すると、非常に素早く不快になることがあります。例えば。 'i'と' n'が符号なしであるとき、 'i

答えて

38

範囲基づくループはクリーナー溶液とすることができる:ここ

for (const auto& i : a) 
{ 

} 

i容器aの要素にconst参照あります。

インデックスが必要な場合や、範囲全体をループしたくない場合は、decltype(a.size())でタイプを取得できます。

for (decltype(a.size()) i = 0; i < a.size(); ++i) { 
} 
+4

範囲ベースのループで1つの問題はインデックスが利用できないことです – RiaD

+0

実際には大きな問題です。インデックスを別々に管理する必要はありません。 – user2381422

+0

ありがとうございます。私はC++ 11が範囲ベースのループを導入したことを知らなかった。 – stepanbujnak

18

ループ内で実行したい機能とコンパイラの機能に応じて、範囲ベースのforループを使用する方が適切です。

ほとんどの状況で、ほとんどの状況で小さな違いはありません 最初の解決策は実際には悪い選択であり、それはコンパイラがあなたに伝えるものです。 第2の解決策は、より良いですが、あなたが直接、シンプルまたはいくつかの将来の変更のための型を定義避けたい場合は、次の操作を実行できます。

auto n = a.size(); 
for (decltype(n) i = 0; i < n; i++) { 
} 

あなたが常に一致するinタイプをバインドするこの方法です。

5

正しいリテラルを使用した場合、0Uです。 autoはint型のリテラルを見るので、これはiの型です。 Uを追加すると、代わりに符号なしのintリテラルが表示されます。それ以外の場合、特にsizeof(size_t)がsizeof(int)(64ビットロングモードで実行されている場合はWindows、OS Xなど)より大きい可能性があるため、decltypeを他の方法として使用することをお勧めします。

+2

標準の 'sizeof(0U)'は常に 'sizeof(size_t)'ですか? – Flexo

+0

@Flexo:それを反映し、別の答えの受け入れを促すために編集された投稿。 –

+0

-1。この答えの前半は、Flexoの言うとおり間違っています。そして、後半は基本的に「他の答えが言うように」と言います。 「別の回答の受け入れを促す」場合は、この回答を削除することができます。 – interjay

-2
for(auto n = a.size(), i = 0; i != n; ++i) { 
} 

...実際の要素だけでなく、インデックスにアクセスする必要がある場合は、おそらく最もクリーンなソリューションです。

更新:それはもうそのきれいに見えないが、

for(auto n = a.size(), i = n*0; i != n; ++i) { 
} 

は、リチャード・スミスコメントの回避策だろう。議論について

+4

これは正しくありません。複数の変数を宣言する 'auto'宣言では、' auto'は各変数に対して独立して導かれ、推定された型が同じでなければコードは不正です。 –

2

intより小さいタイプの、サブス結果はint(整数プロモーションと呼ばれる)に広がること

auto n = a.size(); 
for (auto i = n-n; i<n; ++i) { 
} 

注。

1

のconst-正しい可能な限り、私は通常書くようにしよう:

const auto n(a.size()); 
for (auto i = decltype(n){0}; i < n; ++i) 
{ 
} 

それは非常に簡潔ではありませんが、それはあなたがnの型の0(およびnに初期化変数を望むことは明らかですconst)。

0

ここでは、単純な&クリーナーソリューションを使用しています。

for(auto i: a) 
{ 
} 
関連する問題