繁体   English   中英

C++ reference_wrapper 向量填充错误值

[英]C++ reference_wrapper vector fills with wrong values

我正在尝试在 C++ 中使用引用包装器,因为我希望能够直接更改对象的值,但它们的值都是错误的。 这是一个演示此问题的示例:

#include <vector>
#include <functional>
#include <iostream>
using namespace std;

int main() {
    vector<int> v1 = {1, 2, 3};
    for (int i : v1) {
        cout << i << " ";
    }
    cout << endl;

    vector<reference_wrapper<int>> v2;
    for (int i : v1) {
        v2.push_back(i);
    }
    for (int i : v2) {
        cout << i << " ";
    }
}

它打印

1 2 3
3 3 3

我不确定为什么引用包装向量v2没有复制v1的引用值......

编辑:这是另一个神秘地不起作用的例子。 我不认为这其中有任何悬而未决的参考。

#include <vector>
#include <functional>
#include <iostream>
using namespace std;

int main() {
    vector<int> v1;
    vector<reference_wrapper<int>> v2;

    for (int i = 0; i < 3; i++) {
        v1.push_back(i);
        v2.push_back(v1[i]);
    }

    for (int i : v2) {
        cout << i << " ";
    }
}

它打印9596312 1 2而我希望它打印0 1 2 ...

for循环中

for (int i : v1) {
    v2.push_back(i);
}

您正在从局部变量i构造reference_wrapper s,该变量在迭代后立即销毁,因此存储在v2中的reference_wrapper s 悬空。 对它们的取消引用会导致未定义的行为

你应该声明i作为参考

for (int& i : v1) {
    v2.push_back(i);
}

居住


对于您的编辑,请注意std::vector::push_back可能会导致重新分配v1 ,这使得存储在v2的引用指向v1的元素。

您可以提前使用reserve以避免重新分配。 例如

vector<int> v1;
v1.reserve(3);
vector<reference_wrapper<int>> v2;

for (int i = 0; i < 3; i++) {
    v1.push_back(i);
    v2.push_back(v1[i]);
}

居住

这个:

    vector<reference_wrapper<int>> v2;
    for (int i : v1) {
        v2.push_back(i);
    }

每个push_back构造一个reference_wrapper<int> 它将是对循环中i的引用。 碰巧的是,您的编译器实现很可能碰巧为作用域变量i重用了相同的内存地址。

引用仍然会在循环之后引用那个地址——它恰好在循环结束时没有被触及,所以i拥有的最后一个值是存储在那里的值。

它导致程序通过引用(或通过任何其他方式)在该地址读/写的未定义行为,一种未定义行为是您实际上可以读取内存并从中获取似乎熟悉的值。

循环后变量i已死,因此您应该以相同的方式处理对它的引用。 他们都在风中飘荡……

暂无
暂无

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

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