为什么这个'for'循环不是有效的?

65 c++ arrays c++11

来自Lippman的C++ Primer第5版,第182页,考虑:

int ia[3][4];
for (auto row : ia)
        for (auto col : row)
Run Code Online (Sandbox Code Playgroud)

第一个for遍历ia,其元素是大小为4的数组. 因为row它不是引用,当编译器初始化时,row它会将每个数组元素(与数组类型的任何其他对象一样)转换为指向该数组的第一个元素的指针.结果,在这个循环中的类型rowint*.

我不是很确定我理解这个自动如何工作,但如果我可以假设它自动给出一个基于ia数组成员类型的行的类型,但我不明白为什么这种for行,其中行不是引用,无效.为什么会发生这种情况?"指向该数组的第一个元素的指针",因为什么?

nwp*_*nwp 73

问题在于它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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意&before rowcolwhich表示您需要引用而不是行和列的副本,否则设置col为0将不起作用ia.

  • 注意,`int [3] [4]`的等价物是_not_`std :: array <std :: array <int,3>,4>`,但是`std :: array <std :: array <int, 4>,3>`.这是一个常见的错误,值得指出,因为你也是如此.; - ] (50认同)

Tho*_*mas 38

为了防止腐烂的int[]int*,你可以使用&&

int main() {
    int ia[3][4];
    for (auto && row : ia)
        for (auto && col : row)
            ;
}
Run Code Online (Sandbox Code Playgroud)

  • 或者只是简单的参考就足够了. (9认同)
  • 我在这里使用了`&&`,因为这是[N3853](http://open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3853.htm)中提出的,以支持更多减少`(elem:collection)`语法 (6认同)
  • @MichaelKarcher但是,这不是一个(纯)右值引用 - 这是一个[转发参考](http://en.cppreference.com/w/cpp/utility/forward). (4认同)