std::unordered_map<Key,T,Hash,KeyEqual,Allocator>::try_emplace
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. В этом случае:
emplace, за исключением того, что элемент конструируется следующим образом:value_type(std::piecewise_construct,
std::forward_as_tuple(k),
std::forward_as_tuple(std::forward<Args>(args)...))
emplace, за исключением того, что элемент конструируется следующим образом:value_type(std::piecewise_construct,
std::forward_as_tuple(std::move(k)),
std::forward_as_tuple(std::forward<Args>(args)...))
emplace, за исключением того, что элемент конструируется следующим образом:value_type(std::piecewise_construct,
std::forward_as_tuple(std::forward<K>(k)),
std::forward_as_tuple(std::forward<Args>(args)...))
emplace_hint, за исключением того, что элемент конструируется следующим образом:value_type(std::piecewise_construct,
std::forward_as_tuple(k),
std::forward_as_tuple(std::forward<Args>(args)...))
emplace_hint, за исключением того, что элемент конструируется следующим образом:value_type(std::piecewise_construct,
std::forward_as_tuple(std::move(k)),
std::forward_as_tuple(std::forward<Args>(args)...))
emplace_hint, за исключением того, что элемент конструируется следующим образом:value_type(std::piecewise_construct,
std::forward_as_tuple(std::forward<K>(k)),
std::forward_as_tuple(std::forward<Args>(args)...))
value_type не удовлетворяет требованиям EmplaceConstructible для unordered_map при использовании соответствующего выражения, поведение не определено.-
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 — новый элемент, подлежащий вставке.hash_function()(u.first) != hash_function()(k) || contains(u.first) является true, поведение не определено; здесь u — новый элемент, подлежащий вставке.Если после выполнения операции новое число элементов превышает старое значение max_load_factor() * bucket_count(), выполняется перехеширование.
Если происходит перехеширование (из-за вставки), все итераторы становятся недействительными. В противном случае (если перехеширования нет) итераторы остаются действительными.
Параметры
| k | - | ключ, используемый как для поиска, так и для вставки, если он не найден |
| hint | - | итератор на позицию, перед которой будет вставлен новый элемент |
| args | - | аргументы, передаваемые конструктору элемента |
Возвращаемое значение
emplace:Пара, состоящая из итератора на вставленный элемент (или на элемент, помешавший вставке) и значения типа bool, равного
true тогда и только тогда, когда вставка состоялась.emplace_hint:Итератор на вставленный элемент или на элемент, помешавший вставке.
Сложность
emplace:В среднем амортизированная константная, в худшем случае линейная относительно размера контейнера.
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) (открытая функция-член) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/container/unordered_map/try_emplace