Reputation: 519
I am trying to understand why using operator[]
on unordered_map
in C++ gives me different results when I attempt to modify the value using []
directly vs. store the value in a temporary object. Here's an example:
unordered_map<int,vector<int>> map;
map.emplace(0, vector<int>(10, 1) );
map[0][0] = 2; // this works
cerr << map[0][0] << endl; // prints out 2 - as expected
auto foo = map[0];
foo[1] = 3; // this does not work -- the value in map[0][1] is still 1
cerr << map[0][1] << endl; // prints out 1, expected: 3
My understanding was that map[0]
should return the reference to the associated value, not its copy, but it seems that foo
is a copy since changes to foo
are transient. What am I missing?
Upvotes: 1
Views: 101
Reputation: 4226
Assignment =
operator for vector<T>
type will produce a copy of the value being assigned. That's what happens in auto foo = map[0];
line. foo
is a copy. Docs.
You have several options to go:
map[0][1] = 3
vector<int> &foo = map[0]
and foo[1] = 3
after.vector<int> *foo = &map[0]
and (*foo)[1] = 3
after.Upvotes: 0
Reputation: 69942
construct a new variable (a copy) foo from the return type of map[0]:
auto foo = map[0];
make foo's type be exactly what map[0] returned, even if it's a reference:
decltype(auto) foo = map[0];
make a reference to the type that results from removing any reference specifier from the return type of map[0]:
auto& foo = map[0];
make a const reference to the type that results from removing any reference specifier and const specifier from the return type of map[0]:
auto const& foo = map[0];
Upvotes: 4
Reputation: 42888
You don't want foo
to be a copy of map[0]
, you want it to refer to map[0]
.
So, make foo
a reference:
auto& foo = map[0];
^
Upvotes: 0
Reputation: 96356
map[0] should return the reference to the associated value
It does.
The problem is literally what you wrote:
You store the value in a temporary object, that is, in a copy (auto
!) and not in a reference. Modifying the copy won't change the original object.
Upvotes: 0