[英]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.