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
の種類が行ではない理由がわかりません参照、無効です。なぜこれが起こるのですか? "その配列の最初の要素へのポインタ"、何のため?
問題は、row
はint *
であり、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
には影響しません。
int[]
からint*
への減衰を防ぐには、&&
を使用できます
int main() {
int ia[3][4];
for (auto && row : ia)
for (auto && col : row)
;
}