std::unorde...:try_emplace(3)

πŸ“¦ version 2024.07.05, in nixpkgs unstable, opensuse-leap 16.0

πŸ’– std::unordered_map::try_emplace πŸ’–

Okay bestie, welcome to the C++ Standard Libary manual page for std::unordered_map::try_emplace β€” yes, the header spells it β€œLibary”, and we’re moving on. πŸ’… This one is giving β€œinsert only if the key isn’t already there” main character energy. ✨


🌸 NAME 🌸

std::unordered_map::try_emplace β€” std::unordered_map::try_emplace, literally the name on the tin, no cap. πŸŽ€

✨ Synopsis ✨

Here are the overloads, bestie β€” every single one, exactly as written:

template< class... Args >
std::pair<iterator, bool> try_emplace( const Key& k, Args&&... args );

(1) (since C++17)

template< class... Args >
std::pair<iterator, bool> try_emplace( Key&& k, Args&&... args );

(2) (since C++17)

template< class K, class... Args >
std::pair<iterator, bool> try_emplace( K&& k, Args&&... args );

(3) (since C++26)

template< class... Args >
iterator try_emplace( const_iterator hint, const Key& k, Args&&... args );

(4) (since C++17)

template< class... Args >
iterator try_emplace( const_iterator hint, Key&& k, Args&&... args );

(5) (since C++17)

template< class K, class... Args >
iterator try_emplace( const_iterator hint, K&& k, Args&&... args );

(6) (since C++26)

If a key equivalent to k already exists in the container, it does nothing. Otherwise, it inserts a new element into the container with key k and value constructed with args. In such case:

  1. Behaves like emplace except that the element is constructed as:
value_type(std::piecewise_construct,

           std::forward_as_tuple(k),

           std::forward_as_tuple(std::forward<Args>(args)...))
  1. Behaves like emplace except that the element is constructed as:
value_type(std::piecewise_construct,

           std::forward_as_tuple(std::move(k)),

           std::forward_as_tuple(std::forward<Args>(args)...))
  1. Behaves like emplace except that the element is constructed as:
value_type(std::piecewise_construct,

           std::forward_as_tuple(std::forward<K>(k)),

           std::forward_as_tuple(std::forward<Args>(args)...))
  1. Behaves like emplace_hint except that the element is constructed as:
value_type(std::piecewise_construct,

           std::forward_as_tuple(k),

           std::forward_as_tuple(std::forward<Args>(args)...))
  1. Behaves like emplace_hint except that the element is constructed as:
value_type(std::piecewise_construct,

           std::forward_as_tuple(std::move(k)),

           std::forward_as_tuple(std::forward<Args>(args)...))
  1. Behaves like emplace_hint except that the element is constructed as:
value_type(std::piecewise_construct,

           std::forward_as_tuple(std::forward<K>(k)),

           std::forward_as_tuple(std::forward<Args>(args)...))
  • 1–6) If value_type is not EmplaceConstructible into unordered_map from the corresponding expression, the behavior is undefined. 😭
  • 3) This overload participates in overload resolution only if all following conditions are satisfied:
    • std::is_convertible_v<K&&, const_iterator> and std::is_convertible_v<K&&, iterator> are both false.
    • Hash::is_transparent and KeyEqual::is_transparent are valid and each denotes a type.

If hash_function()(u.first) != hash_function()(k) || contains(u.first) is true, the behavior is undefined, where u is the new element to be inserted.

  • 6) This overload participates in overload resolution only if Hash::is_transparent and KeyEqual::is_transparent are both valid and each denotes a type.

If hash_function()(u.first) != hash_function()(k) || contains(u.first) is true, the behavior is undefined, where u is the new element to be inserted.

If after the operation the new number of elements is greater than old max_load_factor() * bucket_count() a rehashing takes place. If rehashing occurs (due to the insertion), all iterators are invalidated. Otherwise (no rehashing), iterators are not invalidated.

🌈 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.
  • args β€” arguments to forward to the constructor of the element.

🫢 Return value 🫢

  • 1–3) Same as for emplace.
  • 4–6) Same as for emplace_hint.

πŸŽ€ Complexity πŸŽ€

  • 1–3) Same as for emplace.
  • 4–6) Same as for emplace_hint.

πŸ¦‹ Notes πŸ¦‹

Unlike insert or emplace, these functions do not move from rvalue arguments if the insertion does not happen, which makes it easy to manipulate maps whose values are move-only types, such as std::unordered_map<std::string, std::unique_ptr<foo>>. In addition, try_emplace treats the key and the arguments to the mapped_type separately, unlike emplace, which requires the arguments to construct a value_type (that is, a std::pair).

Overloads (3,6) can be called without constructing an object of type Key.

Feature-test macro tea: β˜•

  • __cpp_lib_unordered_map_try_emplace β€” value 201411L, standard (C++17), feature: std::unordered_map::try_emplace, std::unordered_map::insert_or_assign.
  • __cpp_lib_associative_heterogeneous_insertion β€” value 202311L, standard (C++26), feature: Heterogeneous overloads for the remaining member functions in ordered and unordered associative containers. Overloads (3) and (6).

πŸ”₯ Example πŸ”₯

// Run this code

#include <iostream>
#include <string>
#include <unordered_map>
#include <utility>

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

void print_result(auto const& pair)
{
    std::cout << (pair.second ? "inserted: " : "ignored:  ");
    print_node(*pair.first);
}

int main()
{
    using namespace std::literals;
    std::unordered_map<std::string, std::string> m;

    print_result(m.try_emplace("a", "a"s));
    print_result(m.try_emplace("b", "abcd"));
    print_result(m.try_emplace("c", 10, 'c'));
    print_result(m.try_emplace("c", "Won't be inserted"));

    for (const auto& p : m)
        print_node(p);
}

Possible output:

inserted: [a] = a
inserted: [b] = abcd
inserted: [c] = cccccccccc
ignored:  [c] = cccccccccc
[a] = a
[b] = abcd
[c] = cccccccccc

πŸ‘‘ See also πŸ‘‘

  • emplace β€” constructs element in-place (public member function).
  • emplace_hint β€” constructs elements in-place using a hint (public member function).
  • insert β€” inserts elements or nodes (since C++17) (public member function).

That’s the whole page, bestie β€” go insert something iconic. πŸ’…βœ¨ Source: cppreference.com; version/date: 2024.06.10. πŸŽ€

πŸ“¦ where this page comes from