以下代码在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 << ' ';
}