c++ - C++ reference_wrapper vector 使用错误的值填充

标签 c++ c++11 reference reference-wrapper

我试图在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

我不确定为什么引用包装器 vector 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);
}

您正在从局部变量reference_wrapper构造i,该变量在迭代后立即销毁,因此存储在reference_wrapper中的v2悬挂了。对它们的取消引用导致undefined behavior

您应该声明i作为引用为
for (int& i : v1) {
    v2.push_back(i);
}

LIVE

在进行编辑时,请注意 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]);
}

LIVE

关于c++ - C++ reference_wrapper vector 使用错误的值填充,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60751377/

相关文章:

java - 在Java中的方法调用中使用像指针一样的引用

c++ - QGraphicsWidget 的上下文菜单事件

c++ - 有没有更优雅的方式在 C++ 中结合 sprintf 和 std::string?

c++ - 如何在不破坏移动和复制构造函数的情况下声明虚拟析构函数

C++使用显式参数检测自由函数的存在

c++ - 我还应该传递类成员数据作为速度引用吗?

c++ - 有序非重入调用的简单断言?

python - 用cython将c++代码编译成pyd

c++ IF 语句执行,但添加 ELSE 显示错误

vb.net - 从项目引用中获取类型出现在智能感知中的问题