繁体   English   中英

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

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

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

output 是

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

output 符合预期:

DEBUG: vector 1 1 2 3 4 5

命令行是g++-9 test.cc

我错过了什么吗? 这是编译器中的错误吗?

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

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

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

只需使用

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

对于这个向量

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 等等。

例如,如果您将更改矢量,例如

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

那么您将有未定义的行为,因为datos[datos[2]]尝试访问 memory 超出为向量元素分配的 memory 。

无需深入了解此循环

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

实际上等价于以下

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

我错过了什么吗?

您将基于范围的 for 循环与索引到向量中混合 - 相反,选择一种样式。 基于范围的 for 循环的固定示例(它允许您直接迭代范围的元素):

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

手动索引示例:

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

对于基于范围的for循环,该项目已经是一个 int。

正确使用基于范围的for循环

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

或使用传统循环

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