Namespaces
Variants

std::unordered_map<Key,T,Hash,KeyEqual,Allocator>:: try_emplace

From cppreference.net

template < class ... Args >
std:: pair < iterator, bool > try_emplace ( const Key & k, Args && ... args ) ;
(1) (начиная с C++17)
template < class ... Args >
std:: pair < iterator, bool > try_emplace ( Key && k, Args && ... args ) ;
(2) (начиная с C++17)
template < class K, class ... Args >
std:: pair < iterator, bool > try_emplace ( K && k, Args && ... args ) ;
(3) (начиная с C++26)
template < class ... Args >
iterator try_emplace ( const_iterator hint, const Key & k, Args && ... args ) ;
(4) (начиная с C++17)
template < class ... Args >
iterator try_emplace ( const_iterator hint, Key && k, Args && ... args ) ;
(5) (начиная с C++17)
template < class K, class ... Args >
iterator try_emplace ( const_iterator hint, K && k, Args && ... args ) ;
(6) (начиная с C++26)

Если ключ, эквивалентный k уже существует в контейнере, ничего не делает. В противном случае, вставляет новый элемент в контейнер с ключом k и значением, сконструированным с помощью args . В таком случае:

1) Ведёт себя как emplace за исключением того, что элемент конструируется как
value_type ( std:: piecewise_construct ,

std:: forward_as_tuple ( k ) ,

std:: forward_as_tuple ( std:: forward < Args > ( args ) ... ) )
2) Ведёт себя как emplace за исключением того, что элемент конструируется как
value_type ( std:: piecewise_construct ,

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

std:: forward_as_tuple ( std:: forward < Args > ( args ) ... ) )
3) Ведёт себя как emplace за исключением того, что элемент конструируется как
value_type ( std:: piecewise_construct ,

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

std:: forward_as_tuple ( std:: forward < Args > ( args ) ... ) )
4) Ведёт себя как emplace_hint за исключением того, что элемент конструируется как
value_type ( std:: piecewise_construct ,

std:: forward_as_tuple ( k ) ,

std:: forward_as_tuple ( std:: forward < Args > ( args ) ... ) )
5) Ведёт себя как emplace_hint за исключением того, что элемент конструируется как
value_type ( std:: piecewise_construct ,

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

std:: forward_as_tuple ( std:: forward < Args > ( args ) ... ) )
6) Ведёт себя как emplace_hint за исключением того, что элемент конструируется как
value_type ( std:: piecewise_construct ,

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

std:: forward_as_tuple ( std:: forward < Args > ( args ) ... ) )
1-6) Если value_type не является EmplaceConstructible в unordered_map из соответствующего выражения, поведение не определено.
3) Эта перегрузка участвует в разрешении перегрузки только при выполнении всех следующих условий:
  • std:: is_convertible_v < K && , const_iterator > и std:: is_convertible_v < K && , iterator > оба имеют значение false .
  • Hash :: is_transparent и KeyEqual :: is_transparent являются корректными и каждый обозначает тип.
Если hash_function ( ) ( u. first ) ! = hash_function ( ) ( k ) || contains ( u. first ) равно true , поведение не определено, где u - новый элемент для вставки.
6) Эта перегрузка участвует в разрешении перегрузки только если Hash :: is_transparent и KeyEqual :: is_transparent оба являются валидными и каждый обозначает тип.
Если hash_function ( ) ( u. first ) ! = hash_function ( ) ( k ) || contains ( u. first ) равно true , поведение не определено, где u - новый элемент для вставки.

Если после операции новое количество элементов становится больше, чем старое max_load_factor() * bucket_count() происходит повторное хеширование.
Если происходит повторное хеширование (из-за вставки), все итераторы становятся недействительными. В противном случае (без повторного хеширования) итераторы остаются действительными.

Содержание

Параметры

k - ключ, используемый как для поиска, так и для вставки, если не найден
hint - итератор на позицию, перед которой будет вставлен новый элемент
args - аргументы для передачи конструктору элемента

Возвращаемое значение

1-3) То же, что и для emplace :
Пара, состоящая из итератора к вставленному элементу (или к элементу, который предотвратил вставку) и значения bool , установленного в true тогда и только тогда, когда вставка произошла.
4-6) То же, что и для emplace_hint :
Итератор на вставленный элемент или на элемент, который предотвратил вставку.

Сложность

1-3) То же, что и для emplace :
В среднем амортизированная константная сложность, в худшем случае линейная от размера контейнера.
4-6) То же, что и для emplace_hint :
Амортизированная константа в среднем, в худшем случае линейная от размера контейнера.

Примечания

В отличие от insert или emplace , эти функции не перемещают из rvalue-аргументов, если вставка не происходит, что упрощает работу с отображениями, значения которых имеют типы, допускающие только перемещение, такие как std:: unordered_map < std:: string , std:: unique_ptr < foo >> . Кроме того, try_emplace обрабатывает ключ и аргументы для mapped_type раздельно, в отличие от emplace , который требует аргументы для построения value_type (то есть std::pair ).

Перегрузки ( 3 ) и ( 6 ) могут быть вызваны без создания объекта типа Key .

Макрос тестирования возможностей Значение Стандарт Возможность
__cpp_lib_unordered_map_try_emplace 201411L (C++17) std::unordered_map::try_emplace ,
std::unordered_map::insert_or_assign
__cpp_lib_associative_heterogeneous_insertion 202311L (C++26) Гетерогенные перегрузки для оставшихся функций-членов в упорядоченных и неупорядоченных ассоциативных контейнерах . Перегрузки ( 3 ) и ( 6 ) .

Пример

#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);
}

Возможный вывод:

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

Смотрите также

создаёт элемент на месте
(публичная функция-член)
создаёт элементы на месте с использованием подсказки
(публичная функция-член)
вставляет элементы или узлы (начиная с C++17)
(публичная функция-член)