35

In Java's hashmap:

map.put(key, new_value) 

will update the entry of key=key with new_value if it exists in the hashmap.

What's the correct way to do the similar thing in unordered_map of C++11?

I haven't found an API like updateXXX, and the documentation says the unordered_map::insert function will succeed only when there isn't any such pair with a key.

4 Answers 4

62

If you know that the key is in the map, you can utilize operator[] which returns a reference to the mapped value. Hence it will be map[key] = new_value. Be careful, however, as this will insert a (key, new_value) if the key does not already exist in the map.

You can also use find which returns an iterator to the value:

auto it = map.find(key) if(it != map.end()) it->second = new_value; 
Sign up to request clarification or add additional context in comments.

6 Comments

Or std::unordered_map::at. It will throw std::out_of_range exception, if element with specified key does not exists.
Thanks! I used unordered_map::const_iterator it = map.find(key) and I got an error when tried to assign new_value to it->second. auto works perfect. I need learn more about C++..
@Yeclipse That's because you're using a const_iterator - this means that what the iterator is "pointing to" is const (that is, it can't be changed). Modify it to unordered_map::iterator it = map.find(key) and it will work - this is what auto is deducing it as.
The second part is wrong, it->second is not a reference. Assigning to it won't update the value in the map, only the value copy of the iterator.
@jturcotte The dereferencing operation on *it will give you back a reference, which will be a std::pair<const K, T>& for an unordered_map<K, T>. Hence modifying it->second will modify the value that is stored in the container.
|
5

If the type value has no default constructor you can use:

map.emplace(key, new_value).first->second = new_value; 

This also has all the other advantages of emplace vs [] operator and insert.

Comments

1

I thought that Java's map.put inserted the element if it wasn't already in the map and updated it if it was in the map, see put:

put

public V put(K key, V value)

Associates the specified value with the specified key in this map. If the map previously contained a mapping for the key, the old value is replaced.

This would be equivalent to unordered_map::operator[]:

If k matches the key of an element in the container, the function returns a reference to its mapped value.

If k does not match the key of any element in the container, the function inserts a new element with that key and returns a reference to its mapped value. Notice that this always increases the container size by one, even if no mapped value is assigned to the element (the element is constructed using its default constructor).

Comments

-1
  1. Check if the key exists
  2. Update the value by referencing the key
if(map.count(key)){ map[key] = value; } 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.