Namespaces
Variants

std::map<Key,T,Compare,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 в map из соответствующего выражения, поведение не определено.
3) Эта перегрузка участвует в разрешении перегрузки только при выполнении всех следующих условий:
  • std:: is_convertible_v < K && , const_iterator > и std:: is_convertible_v < K && , iterator > оба имеют значение false .
  • Квалифицированный идентификатор Compare :: is_transparent является корректным и обозначает тип.
Если equal_range ( u. first ) == equal_range ( k ) равно false , поведение не определено, где u - новый элемент для вставки.
6) Эта перегрузка участвует в разрешении перегрузки только если квалифицированный идентификатор Compare :: is_transparent является валидным и обозначает тип.
Если equal_range ( u. first ) == equal_range ( k ) равно false , поведение не определено, где u - новый элемент для вставки.

Никакие итераторы или ссылки не инвалидируются.

Содержание

Параметры

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

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

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

Сложность

1-3) То же, что и для emplace :
Логарифмическая от размера контейнера.
4-6) То же, что и для emplace_hint :
Логарифмическая от размера контейнера в общем случае, но амортизированная константная, если новый элемент вставляется непосредственно перед hint .

Примечания

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

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

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

Пример

#include <iostream>
#include <string>
#include <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::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++11)
создаёт элемент на месте
(публичная функция-член)
создаёт элементы на месте с использованием подсказки
(публичная функция-член)
вставляет элементы или узлы (начиная с C++17)
(публичная функция-член)