以下代码在GCC 9.2.1 20190903修订版275330的OpenSUSE Tumbleweed下编译

#include <vector>
#include <iostream>

int main()
{
    std::vector<double> datos = {1, 2, 3, 4, 5, 6};

    std::cout << "DEBUG: vector ";
    for (auto d : datos)
        std::cout << datos[d] << ' ';
    std::cout << std::endl;
}

输出是
DEBUG: vector 2 3 4 5 6 0

但我期待
DEBUG: vector 1 2 3 4 5 6

但是对于其他代码:
#include <vector>
#include <iostream>

int main()
{
    std::vector<double> datos = {1, 1, 2, 3, 4, 5};

    std::cout << "DEBUG: vector ";
    for (auto d : datos)
        std::cout << datos[d] << ' ';
    std::cout << std::endl;
}

输出是预期的:
DEBUG: vector 1 1 2 3 4 5

命令行是g++-9 test.cc
我想念什么吗?这是编译器中的错误吗?

最佳答案

基于范围的for循环中变量d的值

for (auto d : datos)
        std::cout << datos[d] << ' ';

不是 vector 中的索引。它是 vector 的当前元素的值

只需使用
for (auto d : datos)
        std::cout << d << ' ';

对于这个 vector
std::vector<double> datos = {1, 1, 2, 3, 4, 5};

您得到了预期的结果,因为
datos[datos[1]]等于1等于这个元素
std::vector<double> datos = {1, 1, 2, 3, 4, 5};
                               ^^^
datos[datos[1]]再次产生相同的元素。
datos[datos[2]]等于2,依此类推。

例如,如果您将 vector 更改为
std::vector<double> datos = { 5 };

那么您将具有未定义的行为,因为datos[datos[2]]尝试访问的内存超出了Vector元素分配的内存。

无需深入了解此循环
for (auto d : datos)
    std::cout << d << ' ';

实际上等同于以下内容
for ( auto first = std::begin( datos ); first != std::end( datos ); ++first )
{
    auto d = *first;
    std::cout << d << ' ';
}

10-08 05:20