Spec-Zone.ru › C++

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)

Вставляет элементы в контейнер, если в контейнере ещё нет элемента с эквивалентным ключом.

1,2) Вставляет value.
3,4) Вставляет value, используя hint в качестве необязательной подсказки о том, с какого места следует начинать поиск.
5) Вставляет элементы из диапазона [first, last). Если несколько элементов диапазона имеют ключи, сравниваемые как эквивалентные, не определено, какой именно элемент будет вставлен (ожидается рассмотрение LWG2844).
6) Вставляет элементы из списка инициализации ilist. Если несколько элементов диапазона имеют ключи, сравниваемые как эквивалентные, не определено, какой именно элемент будет вставлен (ожидается рассмотрение LWG2844).
7) Если nh — пустой дескриптор узла, ничего не делает. В противном случае вставляет в контейнер элемент, принадлежащий nh, если в контейнере ещё нет элемента с ключом, эквивалентным nh.key(). Поведение не определено, если nh не пуст и get_allocator() != nh.get_allocator().
8) Если nh — пустой дескриптор узла, ничего не делает и возвращает итератор конца. В противном случае вставляет в контейнер элемент, принадлежащий nh, если в контейнере ещё нет элемента с ключом, эквивалентным nh.key(), и возвращает итератор, указывающий на элемент с ключом, эквивалентным nh.key() (независимо от того, была ли вставка успешной). Если вставка успешна, nh перемещается, в противном случае он сохраняет владение элементом. hint используется в качестве необязательной подсказки о том, с какого места следует начинать поиск. Поведение не определено, если nh не пуст и get_allocator() != nh.get_allocator().
9) Если *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.
10) Если *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.

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

1,2) Пара, состоящая из итератора на вставленный элемент (или на элемент, помешавший вставке) и значения bool, равного true тогда и только тогда, когда вставка состоялась.
3,4) Итератор на вставленный элемент или на элемент, помешавший вставке.
5,6) (нет)
7) Объект типа insert_return_type со следующими инициализированными членами:
  • Если nh пуст, inserted равен false, position равен end(), а node пуст.
  • В противном случае, если вставка состоялась, inserted равен true, position указывает на вставленный элемент, а node пуст.
  • Если вставка не удалась, inserted равен false, node содержит прежнее значение nh, а position указывает на элемент с ключом, эквивалентным nh.key().
8) Итератор конца, если nh был пуст; итератор, указывающий на вставленный элемент, если вставка состоялась; и итератор, указывающий на элемент с ключом, эквивалентным nh.key(), если вставка не удалась.
9) Пара, состоящая из итератора на вставленный элемент (или на элемент, помешавший вставке) и значения bool, равного true тогда и только тогда, когда вставка состоялась.
10) Итератор на вставленный элемент или на элемент, помешавший вставке.

Исключения

1-4) Если какая-либо операция выбрасывает исключение, вставка не оказывает никакого эффекта.

Сложность

1-4) В среднем: O(1), в худшем случае O(size()).
5,6) В среднем: O(N), где N — количество вставляемых элементов. В худшем случае: O(N * size() + N).
7-10) В среднем: 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 }

См. также

emplace
создает элемент на месте
(открытая функция-член)
emplace_hint
создает элементы на месте, используя подсказку
(открытая функция-член)
inserter
создает 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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API