Skip to main content

std::unordered_map insert_or_assign() method

// (1) Non const version only
template <class M>
std::pair<iterator, bool> insert_or_assign( const Key& k, M&& obj );

// (2) Non const version only
template <class M>
std::pair<iterator, bool> insert_or_assign( Key&& k, M&& obj );

// (3) Non const version only
template <class M>
iterator insert_or_assign( const_iterator hint, const Key& k, M&& obj );

// (4) Non const version only
template <class M>
iterator insert_or_assign( const_iterator hint, Key&& k, M&& obj );
  • (1-3) If a key equivalent to k already exists in the container, assigns std::forward<M>(obj) to the mapped_type corresponding to the key k.

    If the key does not exist, inserts the new value as if by insert(), constructing it from value_type(k, std::forward<M>(obj)).

  • (2-4) Same as (1-3), except the mapped value is constructed from value_type(std::move(k), std::forward<M>(obj)).

The behavior is undefined if std::is_assignable_v<mapped_type&, M&&> is false.
Invalidation

If an insertion occurs and results in a rehashing of the container, all iterators are invalidated.

Otherwise iterators are not affected. References are not invalidated.

Rehashing occurs only if the new number of elements is greater than max_load_factor() * bucket_count().

Parameters

  • k - the key used both to look up and to insert if not found
  • hint - iterator to the position before which the new element will be inserted
  • obj - the value to insert or assign

Return value

  • (1-2) - The bool component is true if the insertion took place and false if the assignment took place. The iterator component is pointing at the element that was inserted or updated.
  • (3-4) - Iterator pointing at the element that was inserted or updated.

Complexity

Exceptions

(none)

Notes

insert_or_assign returns more information than operator[] and does not require default-constructibility of the mapped type.

Feature testing macro: __cpp_lib_unordered_map_try_emplace.

Example

Main.cpp
#include <iostream>
#include <unordered_map>
#include <string>

auto print_node = [](const auto &node) {
std::cout << "[" << node.first << "] = " << node.second << '\n';
};

auto print_result = [](auto const &pair) {
std::cout << (pair.second ? "inserted: " : "assigned: ");
print_node(*pair.first);
};

int main()
{
std::unordered_map<std::string, std::string> myMap;

print_result( myMap.insert_or_assign("a", "apple" ) );
print_result( myMap.insert_or_assign("b", "banana" ) );
print_result( myMap.insert_or_assign("c", "cherry" ) );
print_result( myMap.insert_or_assign("c", "clementine") );

for (const auto &node : myMap) { print_node(node); }
}
Possible output
inserted: [a] = apple
inserted: [b] = banana
inserted: [c] = cherry
assigned: [c] = clementine
[c] = clementine
[a] = apple
[b] = banana
This article originates from this CppReference page. It was likely altered for improvements or editors' preference. Click "Edit this page" to see all changes made to this document.
Hover to see the original license.

std::unordered_map insert_or_assign() method

// (1) Non const version only
template <class M>
std::pair<iterator, bool> insert_or_assign( const Key& k, M&& obj );

// (2) Non const version only
template <class M>
std::pair<iterator, bool> insert_or_assign( Key&& k, M&& obj );

// (3) Non const version only
template <class M>
iterator insert_or_assign( const_iterator hint, const Key& k, M&& obj );

// (4) Non const version only
template <class M>
iterator insert_or_assign( const_iterator hint, Key&& k, M&& obj );
  • (1-3) If a key equivalent to k already exists in the container, assigns std::forward<M>(obj) to the mapped_type corresponding to the key k.

    If the key does not exist, inserts the new value as if by insert(), constructing it from value_type(k, std::forward<M>(obj)).

  • (2-4) Same as (1-3), except the mapped value is constructed from value_type(std::move(k), std::forward<M>(obj)).

The behavior is undefined if std::is_assignable_v<mapped_type&, M&&> is false.
Invalidation

If an insertion occurs and results in a rehashing of the container, all iterators are invalidated.

Otherwise iterators are not affected. References are not invalidated.

Rehashing occurs only if the new number of elements is greater than max_load_factor() * bucket_count().

Parameters

  • k - the key used both to look up and to insert if not found
  • hint - iterator to the position before which the new element will be inserted
  • obj - the value to insert or assign

Return value

  • (1-2) - The bool component is true if the insertion took place and false if the assignment took place. The iterator component is pointing at the element that was inserted or updated.
  • (3-4) - Iterator pointing at the element that was inserted or updated.

Complexity

Exceptions

(none)

Notes

insert_or_assign returns more information than operator[] and does not require default-constructibility of the mapped type.

Feature testing macro: __cpp_lib_unordered_map_try_emplace.

Example

Main.cpp
#include <iostream>
#include <unordered_map>
#include <string>

auto print_node = [](const auto &node) {
std::cout << "[" << node.first << "] = " << node.second << '\n';
};

auto print_result = [](auto const &pair) {
std::cout << (pair.second ? "inserted: " : "assigned: ");
print_node(*pair.first);
};

int main()
{
std::unordered_map<std::string, std::string> myMap;

print_result( myMap.insert_or_assign("a", "apple" ) );
print_result( myMap.insert_or_assign("b", "banana" ) );
print_result( myMap.insert_or_assign("c", "cherry" ) );
print_result( myMap.insert_or_assign("c", "clementine") );

for (const auto &node : myMap) { print_node(node); }
}
Possible output
inserted: [a] = apple
inserted: [b] = banana
inserted: [c] = cherry
assigned: [c] = clementine
[c] = clementine
[a] = apple
[b] = banana
This article originates from this CppReference page. It was likely altered for improvements or editors' preference. Click "Edit this page" to see all changes made to this document.
Hover to see the original license.