36

次のコードで、署名付き/未署名の不一致という警告が表示されます。

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

問題は、0 を割り当てると、 ではなくiになることです。だから何が良い:intsize_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_tなく 同じ目的で使用するだけなので、最初のものの方が好きです。size_tauto

4

8 に答える 8

51

範囲ベースのループは、よりクリーンなソリューションになる可能性があります。

for (const auto& i : a)
{

}

ここでiは、constcontainer の要素への参照aです。

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

for (decltype(a.size()) i = 0; i < a.size(); ++i) {
}
于 2013-07-06T17:08:18.023 に答える
18

ループ内で何をしたいのか、およびコンパイラの機能によっては、範囲ベースの for ループがより良い解決策になる場合があります。

提示された解決策はすべて、ほとんどの状況で悪くはありませんが、わずかな違いがあります。最初の解決策は実際にはより悪い選択であり、それはまさにコンパイラがあなたに伝えていることです。2番目の解決策の方が優れていますが、単純化または将来の変更のためにタイプを直接定義したくない場合は、次のことができます。

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

iこのようにして、とタイプをバインドして、n常に互いに一致するようにします。

于 2013-07-06T17:18:01.930 に答える
6

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

于 2013-07-06T17:26:31.947 に答える
4

可能な限り const に正しくなるように、私は通常次のように書きます。

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

あまり簡潔ではありませんが、変数をnの型の 0 に初期化する必要があることは明らかです (そしてnは ですconst)。

于 2014-04-19T17:42:17.837 に答える
2

議論のために:

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

よりも小さい型の場合、減算の結果は(整数昇格と呼ばれる)intに拡大されることに注意してください。int

于 2013-07-09T22:54:16.233 に答える
0

これを機能させるためのシンプルでクリーンなソリューションを次に示します。

for(auto i: a)
{
}
于 2018-02-11T15:51:26.120 に答える