Spec-Zone.ru › C++

std::set<Key,Compare,Allocator>::insert

std::pair<iterator, bool> insert( const value_type& value );
(1)
std::pair<iterator, bool> insert( value_type&& value );
(2) (начиная с C++11)
iterator insert( iterator pos, const value_type& value );
(3) (до C++11)
iterator insert( const_iterator pos, const value_type& value );
(начиная с C++11)
iterator insert( const_iterator pos, value_type&& value );
(4) (начиная с C++11)
template< class InputIt >
void insert( InputIt first, InputIt last );
(5)
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 pos, node_type&& nh );
(8) (начиная с C++17)
template< class K >
std::pair<iterator, bool> insert( K&& x );
(9) (начиная с C++23)
template< class K >
iterator insert( const_iterator pos, K&& x );
(10) (начиная с C++23)

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

1,2) Вставляет value.
3,4) Вставляет value в позицию, максимально близкую к позиции непосредственно перед pos.
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 перемещается, в противном случае он сохраняет владение элементом. Элемент вставляется в позицию, максимально близкую к позиции непосредственно перед pos. Поведение не определено, если nh не пуст и get_allocator() != nh.get_allocator().
9) Если *this уже содержит элемент, который прозрачно сравнивается с x как эквивалентный, ничего не делает. В противном случае создаёт объект u типа value_type с помощью std::forward<K>(x), а затем вставляет u в *this. Если equal_range(u) == equal_range(x) является false, поведение не определено. Тип value_type должен удовлетворять требованиям EmplaceConstructible для set из std::forward<K>(x). Эта перегрузка участвует в разрешении перегрузки, только если квалифицированный идентификатор Compare::is_transparent допустим и обозначает тип. Это позволяет вызывать функцию без создания экземпляра Key.
10) Если *this уже содержит элемент, который прозрачно сравнивается с x как эквивалентный, ничего не делает. В противном случае создаёт объект u типа value_type с помощью std::forward<K>(x), а затем вставляет u в *this в позицию, максимально близкую к позиции непосредственно перед pos. Если equal_range(u) == equal_range(x) является false, поведение не определено. Тип value_type должен удовлетворять требованиям EmplaceConstructible для set из std::forward<K>(x). Эта перегрузка участвует в разрешении перегрузки, только если:
  • std::is_convertible_v<K&&, const_iterator> и std::is_convertible_v<K&&, iterator> являются false, и
  • квалифицированный идентификатор Compare::is_transparent допустим и обозначает тип,
что в совокупности позволяет вызывать функцию без создания экземпляра Key.

Итераторы и ссылки не становятся недействительными. Если вставка прошла успешно, указатели и ссылки на элемент, полученные, пока он находился в дескрипторе узла, становятся недействительными, а указатели и ссылки, полученные на этот элемент до его извлечения, становятся действительными.(начиная с C++17)

Параметры

pos - итератор на позицию, перед которой будет вставлен новый элемент
value - значение вставляемого элемента
first, last - пара итераторов, задающая исходный диапазон элементов для вставки
ilist - список инициализации, из которого вставляются значения
nh - совместимый дескриптор узла
x - значение любого типа, которое можно прозрачно сравнить с ключом
Требования к типам
-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,2) Логарифмическая относительно размера контейнера, O(log(size())).
3,4) Амортизированная константная, если вставка происходит в позицию непосредственно после(до C++11)перед(начиная с C++11) pos, иначе логарифмическая относительно размера контейнера.
5,6) O(N·log(size() + N)), где N — количество вставляемых элементов.
7) Логарифмическая относительно размера контейнера, O(log(size())).
8) Амортизированная константная, если вставка происходит в позицию непосредственно перед pos, иначе логарифмическая относительно размера контейнера.
9) Логарифмическая относительно размера контейнера, O(log(size())).
10) Амортизированная константная, если вставка происходит в позицию непосредственно перед pos, иначе логарифмическая относительно размера контейнера.

Примечания

Вставка с подсказкой (3,4) не возвращает логическое значение, чтобы её сигнатура соответствовала сигнатуре позиционной вставки в последовательные контейнеры, например std::vector::insert. Это позволяет создавать универсальные вставщики, например std::inserter. Один из способов проверить успешность вставки с подсказкой — сравнить size() до и после.

Перегрузки (5,6) часто реализуются как цикл, вызывающий перегрузку (3) с end() в качестве подсказки; они оптимизированы для добавления отсортированной последовательности (например, другого std::set), наименьший элемент которой больше последнего элемента в *this.

Макрос проверки поддержки возможностей Значение Стандарт Возможность
__cpp_lib_associative_heterogeneous_insertion 202311L (C++26) Гетерогенные перегрузки остальных функций-членов упорядоченных ассоциативных и неупорядоченных ассоциативных контейнеров. (9,10)

Пример

#include <cassert>
#include <iostream>
#include <set>

int main()
{
    std::set<int> set;
    
    auto result_1 = set.insert(3);
    assert(result_1.first != set.end()); // it is a valid iterator
    assert(*result_1.first == 3);
    if (result_1.second)
        std::cout << "insert done\n";
    
    auto result_2 = set.insert(3);
    assert(result_2.first == result_1.first); // same iterator
    assert(*result_2.first == 3);
    if (!result_2.second)
        std::cout << "no insertion\n";
}

Вывод:

insert done
no insertion

Отчёты об ошибках

Следующие отчёты об ошибках, изменяющие поведение, были применены ретроактивно к ранее опубликованным стандартам C++.

DR Применён к Опубликованное поведение Корректное поведение
LWG 233 C++98 pos был лишь подсказкой и мог быть полностью проигнорирован вставка должна происходить
в позицию, максимально близкую к позиции
непосредственно перед pos
LWG 264 C++98 для сложности перегрузки (5) требовалось линейное время, если
диапазон [first, last) отсортирован согласно Compare
требование линейной сложности
в этом частном случае удалено
LWG 316 C++98 для возвращаемого значения перегрузки (1) не было указано,
какое значение bool означает успешную вставку
успешная вставка
обозначается значением true

См. также

emplace
(C++11)
создаёт элемент на месте
(функция-член класса)
emplace_hint
(C++11)
создаёт элементы на месте, используя подсказку
(функция-член класса)
inserter
создаёт std::insert_iterator типа, выводимого из аргумента
(шаблон функции)

© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/container/set/insert

Spec-Zone.ru

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