std::vector の反復処理: 符号なしインデックス変数と符号付きインデックス変数の比較 質問する

std::vector の反復処理: 符号なしインデックス変数と符号付きインデックス変数の比較 質問する

C++ でベクトルを反復処理する正しい方法は何ですか?

次の 2 つのコード フラグメントを検討してください。これは正常に動作します。

for (unsigned i=0; i < polygon.size(); i++) {
    sum += polygon[i];
}

そしてこれ:

for (int i=0; i < polygon.size(); i++) {
    sum += polygon[i];
}

を生成しますwarning: comparison between signed and unsigned integer expressions

このunsigned変数は私には少し恐ろしく見えますし、unsigned変数は正しく使用しないと危険な場合があることも知っていますが、これは正しいのでしょうか?

ベストアンサー1

逆方向に反復するには、この答え

前方反復処理は、ほとんど同じです。反復子を変更し、減分と増分を入れ替えるだけです。反復子を優先する必要があります。 をstd::size_tインデックス変数型として使用するように言う人もいます。ただし、これは移植性がありません。常にコンテナの typedef を使用してください(前方反復処理の場合は変換のみで済むかもしれませんが、が の typedef よりも広い場合に を使用すると、size_type後方反復処理の場合は実際には完全に失敗する可能性があります)。std::size_tstd::size_tsize_type


std::vector の使用

イテレータの使用

for(std::vector<T>::iterator it = v.begin(); it != v.end(); ++it) {
    /* std::cout << *it; ... */
}

重要なのは、定義がわからないイテレータには常にプレフィックス増分形式を使用することです。これにより、コードが可能な限り汎用的に実行されるようになります。

範囲の使用 C++11

for(auto const& value: a) {
     /* std::cout << value; ... */

インデックスの使用

for(std::vector<int>::size_type i = 0; i != v.size(); i++) {
    /* std::cout << v[i]; ... */
}

配列の使用

イテレータの使用

for(element_type* it = a; it != (a + (sizeof a / sizeof *a)); it++) {
    /* std::cout << *it; ... */
}

範囲の使用 C++11

for(auto const& value: a) {
     /* std::cout << value; ... */

インデックスの使用

for(std::size_t i = 0; i != (sizeof a / sizeof *a); i++) {
    /* std::cout << a[i]; ... */
}

ただし、このアプローチによってどのような問題が発生する可能性があるかについては、後方反復の回答を読んでくださいsizeof

おすすめ記事