I'm trying to use reference wrappers in C++, since I want to be able to directly alter objects' values, but their values are all wrong. Here's an example that demonstrates this problem:
#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 << " ";
}
}
It prints
1 2 3
3 3 3
I'm not sure why the reference wrapper vector v2
is not copying the referred values in v1
...
EDIT: Here's another example that also mysteriously doesn't work. I don't think there are any dangling references in this one.
#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 << " ";
}
}
It prints 9596312 1 2
while I expect it to print 0 1 2
...
In the for
loop
for (int i : v1) {
v2.push_back(i);
}
You're constructing reference_wrapper
s from the local variable i
, which is destroyed immediately after the iteration, so reference_wrapper
s stored in v2
are dangled. Dereference on them leads to undefined behavior.
You should declare i
as reference as
for (int& i : v1) {
v2.push_back(i);
}
For your edit, note that std::vector::push_back
might cause reallocation on v1
, which makes the references stored in v2
refering to the elements of v1
dangled.
You can use reserve
in advance to avoid reallocation. e.g.
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]);
}