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) |
Вставляет элемент или элементы в контейнер, если в контейнере ещё нет элемента с эквивалентным ключом.
value. value в позицию, максимально близкую к позиции непосредственно перед pos. [first, last). Если несколько элементов диапазона имеют ключи, сравниваемые как эквивалентные, не определено, какой элемент будет вставлен (ожидает рассмотрения LWG2844).ilist. Если несколько элементов диапазона имеют ключи, сравниваемые как эквивалентные, не определено, какой элемент будет вставлен (ожидает рассмотрения LWG2844).nh — пустой дескриптор узла, ничего не делает. В противном случае вставляет принадлежащий nh элемент в контейнер, если в контейнере ещё нет элемента с ключом, эквивалентным nh.key(). Поведение не определено, если nh не пуст и get_allocator() != nh.get_allocator().nh — пустой дескриптор узла, ничего не делает и возвращает итератор на конец. В противном случае вставляет принадлежащий nh элемент в контейнер, если в контейнере ещё нет элемента с ключом, эквивалентным nh.key(), и возвращает итератор, указывающий на элемент с ключом, эквивалентным nh.key() (независимо от того, прошла ли вставка успешно). Если вставка прошла успешно, nh перемещается, в противном случае он сохраняет владение элементом. Элемент вставляется в позицию, максимально близкую к позиции непосредственно перед pos. Поведение не определено, если nh не пуст и get_allocator() != nh.get_allocator().*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.*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. |
||
Возвращаемое значение
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(log(size())).pos, иначе логарифмическая относительно размера контейнера.O(N·log(size() + N)), где N — количество вставляемых элементов.O(log(size())).pos, иначе логарифмическая относительно размера контейнера.O(log(size())).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 |
См. также
|
(C++11) | создаёт элемент на месте (функция-член класса) |
|
(C++11) | создаёт элементы на месте, используя подсказку (функция-член класса) |
создаёт std::insert_iterator типа, выводимого из аргумента (шаблон функции) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/container/set/insert