std::unordered_set<Key,Hash,KeyEqual,Allocator>::insert
std::pair<iterator,bool> insert( const value_type& value ); | (1) | (начиная с C++11) |
std::pair<iterator,bool> insert( value_type&& value ); | (2) | (начиная с C++11) |
iterator insert( const_iterator hint, const value_type& value ); | (3) | (начиная с C++11) |
iterator insert( const_iterator hint, value_type&& value ); | (4) | (начиная с C++11) |
template< class InputIt > void insert( InputIt first, InputIt last ); | (5) | (начиная с C++11) |
void insert( std::initializer_list<value_type> ilist ); | (6) | (начиная с C++11) |
insert_return_type insert( node_type&& nh ); | (7) | (начиная с C++17) |
iterator insert( const_iterator hint, node_type&& nh ); | (8) | (начиная с C++17) |
template< class K > std::pair<iterator, bool> insert( K&& obj ); | (9) | (начиная с C++23) |
template< class K > iterator insert( const_iterator hint, K&& obj ); | (10) | (начиная с C++23) |
Вставляет элементы в контейнер, если в контейнере ещё нет элемента с эквивалентным ключом.
value.value, используя hint в качестве необязательной подсказки о том, с какого места следует начинать поиск.[first, last). Если несколько элементов диапазона имеют ключи, сравниваемые как эквивалентные, не определено, какой именно элемент будет вставлен (ожидается рассмотрение LWG2844).ilist. Если несколько элементов диапазона имеют ключи, сравниваемые как эквивалентные, не определено, какой именно элемент будет вставлен (ожидается рассмотрение LWG2844).nh — пустой дескриптор узла, ничего не делает. В противном случае вставляет в контейнер элемент, принадлежащий nh, если в контейнере ещё нет элемента с ключом, эквивалентным nh.key(). Поведение не определено, если nh не пуст и get_allocator() != nh.get_allocator().nh — пустой дескриптор узла, ничего не делает и возвращает итератор конца. В противном случае вставляет в контейнер элемент, принадлежащий nh, если в контейнере ещё нет элемента с ключом, эквивалентным nh.key(), и возвращает итератор, указывающий на элемент с ключом, эквивалентным nh.key() (независимо от того, была ли вставка успешной). Если вставка успешна, nh перемещается, в противном случае он сохраняет владение элементом. hint используется в качестве необязательной подсказки о том, с какого места следует начинать поиск. Поведение не определено, если nh не пуст и get_allocator() != nh.get_allocator().*this уже содержит элемент, который прозрачно сравнивается как эквивалентный obj, ничего не делает. В противном случае создает объект u типа value_type с помощью std::forward<K>(obj), а затем вставляет u в *this. Если equal_range(u) != hash_function()(obj) || contains(u) является true, поведение не определено. value_type должен удовлетворять требованиям EmplaceConstructible для unordered_set из std::forward<K>(obj). Эта перегрузка участвует в разрешении перегрузки, только если Hash::is_transparent и KeyEqual::is_transparent корректны и каждый из них обозначает тип. Предполагается, что такой Hash можно вызвать как с типом K, так и с типом Key, а KeyEqual является прозрачным; вместе это позволяет вызывать эту функцию, не создавая экземпляр Key.*this уже содержит элемент, который прозрачно сравнивается как эквивалентный obj, ничего не делает. В противном случае создает объект u типа value_type с помощью std::forward<K>(obj), а затем вставляет u в *this. Template:hint используется в качестве необязательной подсказки о том, с какого места следует начинать поиск. Если equal_range(u) != hash_function()(obj) || contains(u) является true, поведение не определено. value_type должен удовлетворять требованиям EmplaceConstructible для unordered_set из std::forward<K>(obj). Эта перегрузка участвует в разрешении перегрузки, только если:
-
std::is_convertible_v<K&&, const_iterator>иstd::is_convertible_v<K&&, iterator>оба являютсяfalse, и -
Hash::is_transparentиKeyEqual::is_transparentкорректны и каждый из них обозначает тип. Предполагается, что такойHashможно вызвать как с типомK, так и с типомKey, аKeyEqualявляется прозрачным;
Key. Если после операции новое количество элементов больше старого значения max_load_factor() * bucket_count(), выполняется рехеширование.
Если происходит рехеширование (из-за вставки), все итераторы становятся недействительными. В противном случае (если рехеширования нет) итераторы не становятся недействительными. Если вставка успешна, указатели и ссылки на элемент, полученные, пока он находился во владении дескриптора узла, становятся недействительными, а указатели и ссылки на этот элемент, полученные до его извлечения, становятся действительными.(начиная с C++17)
Параметры
| hint | - | итератор, используемый в качестве подсказки о том, куда вставить содержимое |
| value | - | значение вставляемого элемента |
| first, last | - | пара итераторов, определяющая исходный диапазон вставляемых элементов |
| ilist | - | список инициализации, из которого берутся вставляемые значения |
| nh | - | совместимый дескриптор узла |
| obj | - | значение любого типа, которое можно прозрачно сравнить с ключом |
| Требования к типам | ||
-InputIt должен удовлетворять требованиям LegacyInputIterator. |
||
Возвращаемое значение
true тогда и только тогда, когда вставка состоялась.insert_return_type со следующими инициализированными членами: - Если
nhпуст,insertedравенfalse,positionравенend(), аnodeпуст. - В противном случае, если вставка состоялась,
insertedравенtrue,positionуказывает на вставленный элемент, аnodeпуст. - Если вставка не удалась,
insertedравенfalse,nodeсодержит прежнее значениеnh, аpositionуказывает на элемент с ключом, эквивалентнымnh.key().
nh был пуст; итератор, указывающий на вставленный элемент, если вставка состоялась; и итератор, указывающий на элемент с ключом, эквивалентным nh.key(), если вставка не удалась.true тогда и только тогда, когда вставка состоялась.Исключения
Сложность
O(1), в худшем случае O(size()).O(N), где N — количество вставляемых элементов. В худшем случае: O(N * size() + N).O(1), в худшем случае O(size()).Примечания
Вставка с подсказкой (3,4) не возвращает логическое значение, чтобы сигнатура соответствовала позиционной вставке в последовательные контейнеры, такие как std::vector::insert. Это позволяет создавать универсальные вставщики, такие как std::inserter. Один из способов проверить успешность вставки с подсказкой — сравнить size() до и после операции.
| Макрос проверки поддержки возможностей | Значение | Стандарт | Возможность |
|---|---|---|---|
__cpp_lib_associative_heterogeneous_insertion | 202311L | (C++26) | Гетерогенные перегрузки для остальных функций-членов упорядоченных ассоциативных и неупорядоченных ассоциативных контейнеров. (9,10) |
Пример
#include <array>
#include <iostream>
#include <unordered_set>
std::ostream& operator<<(std::ostream& os, std::unordered_set<int> const& s)
{
for (os << '[' << s.size() << "] { "; int i : s)
os << i << ' ';
return os << "}\n";
}
int main ()
{
std::unordered_set<int> nums{2, 3, 4};
std::cout << "1) Initially: " << nums << std::boolalpha;
auto p = nums.insert(1); // insert element, overload (1)
std::cout << "2) '1' was inserted: " << p.second << '\n';
std::cout << "3) After insertion: " << nums;
nums.insert(p.first, 0); // insert with hint, overload (3)
std::cout << "4) After insertion: " << nums;
std::array<int, 4> a = {10, 11, 12, 13};
nums.insert(a.begin(), a.end()); // insert range, overload (5)
std::cout << "5) After insertion: " << nums;
nums.insert({20, 21, 22, 23}); // insert initializer_list, (6)
std::cout << "6) After insertion: " << nums;
std::unordered_set<int> other_nums = {42, 43};
auto node = other_nums.extract(other_nums.find(42));
nums.insert(std::move(node)); // insert node, overload (7)
std::cout << "7) After insertion: " << nums;
node = other_nums.extract(other_nums.find(43));
nums.insert(nums.begin(), std::move(node)); // insert node with hint, (8)
std::cout << "8) After insertion: " << nums;
}
Возможный вывод:
1) Initially: [3] { 4 3 2 }
2) '1' was inserted: true
3) After insertion: [4] { 1 2 3 4 }
4) After insertion: [5] { 0 1 2 3 4 }
5) After insertion: [9] { 13 12 11 10 4 3 2 1 0 }
6) After insertion: [13] { 23 22 13 12 11 10 21 4 20 3 2 1 0 }
7) After insertion: [14] { 42 23 22 13 12 11 10 21 4 20 3 2 1 0 }
8) After insertion: [15] { 43 42 23 22 13 12 11 10 21 4 20 3 2 1 0 }
См. также
| создает элемент на месте (открытая функция-член) |
|
| создает элементы на месте, используя подсказку (открытая функция-член) |
|
создает std::insert_iterator типа, выводимого из аргумента (шаблон функции) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/container/unordered_set/insert