繁体   English   中英

打印 reference_wrapper 的向量<int>

[英]Printing a vector of reference_wrapper<int>

我有以下可在 clang 下运行的测试代码。

#include <algorithm>
#include <vector>
#include <iostream>

int main() {

    std::vector<int> vs{1, 2, 4, 5};

    std::vector<std::reference_wrapper<int>> vs1;

    for (int i : vs) {
        std::cout << "loop: " << i << std::endl;
        vs1.emplace_back(i);
    }

    for (auto p : vs1) {
        std::cout << p << std::endl;
    }
    return 0;
}

您可以将其插入https://rextester.com/l/cpp_online_compiler_clang (或本地)。 结果是:

loop: 1
loop: 2
loop: 4
loop: 5
5
5
5
5
  1. 我一直期待 1、2、4、5,而不是 5。
  2. 该代码不适用于非 clang。 问题出在哪里?

i是其声明for循环中的局部变量 它是vs向量中每个int副本 因此,您(通过emplace_back()调用)创建reference_wrapper局部变量的reference_wrapper对象,在被引用变量 ( i ) 的生命周期结束后保持引用活动。 这是未定义的行为

解决方法是让i成为对每个int引用,而不是copy ,这样reference_wrapper s 就如预期的那样reference_wrapper vsint s:

for (int& i : vs)

首先,您忘记了<functional>标头。 其次, reference_wrapper<int>存储int引用 不是它的价值。 所以在这个循环中:

for (int i : vs) {
    std::cout << "loop: " << i << std::endl;
    vs1.emplace_back(i);
}

您正在更改i值,但未更改其在内存中的位置。 它始终是相同的变量。 这就是为什么它打印存储在该变量中的最后一个值,即5

你可以想象这个基于范围的 for 循环

for (int i : vs) {
    std::cout << "loop: " << i << std::endl;
    vs1.emplace_back(i);
}

以下方式

for ( auto first = vs.begin(); first != vs.end(); ++first )
{
    int i = *first;
    vs1.emplace_back(i);
}

那是在循环内,您正在处理退出循环后将不存在的局部变量 i 。

您需要使用对向量元素的引用,例如

for (int &i : vs) {
    std::cout << "loop: " << i << std::endl;
    vs1.emplace_back(i);
}

暂无
暂无

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

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