简体   繁体   English

使用 initializer_list 构造的 std::vector 未按预期运行

[英]std::vector constructed with initializer_list not behaving as expected

The following code is compiled under OpenSUSE Tumbleweed with GCC 9.2.1 20190903 revision 275330以下代码在 OpenSUSE Tumbleweed 下用 GCC 9.2.1 20190903 修订版 275330 编译

#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;
}

The output is output 是

DEBUG: vector 2 3 4 5 6 0

But I was expecting但我期待

DEBUG: vector 1 2 3 4 5 6

Yet for this other code:然而对于这个其他代码:

#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;
}

The output is as expected: output 符合预期:

DEBUG: vector 1 1 2 3 4 5

Command line is g++-9 test.cc命令行是g++-9 test.cc

Am I missing something?我错过了什么吗? Is this a bug in the compiler?这是编译器中的错误吗?

The value of the variable d in the range-based for loop基于范围的for循环中变量d的值

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

is not an index in the vector.不是向量中的索引。 It is a value of the current element of the vector它是向量的当前元素的值

Just use只需使用

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

For this vector对于这个向量

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

you got the expected result because你得到了预期的结果,因为

datos[datos[1]] is equal to 1 that is it is equal to this element datos[datos[1]]等于 1 即等于这个元素

std::vector<double> datos = {1, 1, 2, 3, 4, 5};
                               ^^^

datos[datos[1]] again yields the same element. datos[datos[1]]再次产生相同的元素。

datos[datos[2]] is equal to 2 and so on. datos[datos[2]]等于 2 等等。

If you for example will change the vector like例如,如果您将更改矢量,例如

std::vector<double> datos = { 5 };

then you will have undefined behavior because datos[datos[2]] tries to access memory beyond the allocated memory for the vector's elements.那么您将有未定义的行为,因为datos[datos[2]]尝试访问 memory 超出为向量元素分配的 memory 。

Without deeping in details this loop无需深入了解此循环

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

in fact is equivalent to the following实际上等价于以下

for ( auto first = std::begin( datos ); first != std::end( datos ); ++first )
{
    auto d = *first;
    std::cout << d << ' ';
}

Am I missing something?我错过了什么吗?

You mixed range based for loops with indexing into a vector - instead, pick one style.您将基于范围的 for 循环与索引到向量中混合 - 相反,选择一种样式。 Fixed example with range-based for loop (which allows you to directly iterate over the elements of a range):基于范围的 for 循环的固定示例(它允许您直接迭代范围的元素):

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

Example with manual indices:手动索引示例:

for (std::size_t i = 0; i < datos.size(); ++i)
    std::cout << datos[i] << ' ';

For a range-based for loop, the item is already an int.对于基于范围的for循环,该项目已经是一个 int。

Either use range-based for loop correctly正确使用基于范围的for循环

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

Or use traditional loop或使用传统循环

for (size_t d = 0; d < datos.size(); ++d)
    std::cout << datos[d] << ' ';

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM