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) |
| (3) | ||
iterator insert( iterator pos, const value_type& value ); | (до 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) |
Вставляет элемент(ы) в контейнер, если в контейнере ещё нет элемента с эквивалентным ключом.
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().Никакие итераторы или ссылки не становятся недействительными. Если вставка успешна, указатели и ссылки на элемент, полученные, пока он хранится в дескрипторе узла, становятся недействительными, а указатели и ссылки, полученные на этот элемент до его извлечения, становятся действительными.(с C++17)
Параметры
| pos | - | итератор на позицию перед которой будет вставлен новый элемент |
| value | - | значение элемента для вставки |
| first, last | - | диапазон элементов для вставки |
| ilist | - | список инициализации для вставки значений из него |
| nh | - | совместимый дескриптор узла |
| Требования к типу | ||
-InputIt должен соответствовать требованиям LegacyInputIterator. |
||
Возвращаемое значение
bool, установленного в true тогда и только тогда, когда вставка произошла.insert_return_type с инициализированными членами следующим образом: - Если
nhпустой,inserted—false,position—end(), иnodeпустой. - В противном случае, если вставка произошла,
inserted—true,positionуказывает на вставленный элемент, иnodeпустой. - Если вставка не удалась,
inserted—false,nodeимеет предыдущее значениеnh, иpositionуказывает на элемент с ключом, эквивалентнымnh.key().
nh был пустым, итератор, указывающий на вставленный элемент, если вставка произошла, и итератор, указывающий на элемент с ключом, эквивалентным nh.key(), если она не удалась.Исключение
Сложность
O(log(size())).pos, логарифмическая относительно размера контейнера в противном случае.O(N·log(size() + N)), где N — число элементов для вставки.O(log(size())).pos, логарифмическая относительно размера контейнера в противном случае.Примечания
Вставка с подсказкой (3,4) не возвращает булево значение, чтобы быть совместимой по сигнатуре с позиционной вставкой в последовательных контейнерах, таких как std::vector::insert. Это позволяет создавать универсальные вставки, такие как std::inserter. Один из способов проверить успех вставки с подсказкой — сравнить size() до и после.
Перегрузки (5,6) часто реализуются как цикл, который вызывает перегрузку (3) с end() в качестве подсказки; они оптимизированы для добавления отсортированной последовательности (например, другого множества), наименьший элемент которой больше последнего элемента в *this.
Пример
#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/w/cpp/container/set/insert