web-dev-qa-db-ja.com

なぜこの「for」ループが有効ではないのですか?

LippmanによるC++ Primer 5th Editionの182ページから、以下を検討してください。

int ia[3][4];
for (auto row : ia)
        for (auto col : row)

最初のforは、要素がサイズ4の配列であるiaを反復処理します。rowは参照ではないため、コンパイラがrowを初期化するとき、各配列要素(配列型の他のオブジェクトと同様)をポインターに変換しますその配列の最初の要素。結果として、このループではrowの型はint*

私はこの自動の仕組みを理解しているかどうかは確かではありませんが、ia配列メンバータイプに基づいて自動的に行に型を与えると仮定できる場合、このようなforの種類が行ではない理由がわかりません参照、無効です。なぜこれが起こるのですか? "その配列の最初の要素へのポインタ"、何のため?

65
user5585984

問題は、rowint *であり、int[4]ではなく、配列がポインターに減衰し、ポインターが指す要素の数を自動的に知る方法がないためです。

この問題を回避するために、すべてが正常に機能するstd::arrayが追加されました。

#include <array>

int main() {
    std::array<std::array<int, 4>, 3> ia;
    for (auto &row : ia){
        for (auto &col : row){
            col = 0;
        }
    }
}

rowおよびcolの前の&に注意してください。これは、行と列のコピーではなく参照が必要であることを示します。そうでない場合、colを0に設定してもiaには影響しません。

73
nwp

int[]からint*への減衰を防ぐには、&&を使用できます

int main() {
    int ia[3][4];
    for (auto && row : ia)
        for (auto && col : row)
            ;
}
38
Thomas