簡體   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