lynxoid
lynxoid

Reputation: 519

modifying the value of a complex type in a C++ unordered_map

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

Answers (4)

Ivan Gritsenko
Ivan Gritsenko

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:

  1. map[0][1] = 3
  2. vector<int> &foo = map[0] and foo[1] = 3 after.
  3. vector<int> *foo = &map[0] and (*foo)[1] = 3 after.

Upvotes: 0

Richard Hodges
Richard Hodges

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

flogram_dev
flogram_dev

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

Karoly Horvath
Karoly Horvath

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

Related Questions