std::map<Key,T,Compare,Allocator>::insert
std::pair<iterator, bool> insert( const value_type& value ); | (1) | |
template< class P > std::pair<iterator, bool> insert( P&& value ); | (2) | (с C++11) |
std::pair<iterator, bool> insert( value_type&& value ); | (3) | (с C++17) |
| (4) | ||
iterator insert( iterator pos, const value_type& value ); | (до C++11) | |
iterator insert( const_iterator pos, const value_type& value ); | (с C++11) | |
template< class P > iterator insert( const_iterator pos, P&& value ); | (5) | (с C++11) |
iterator insert( const_iterator pos, value_type&& value ); | (6) | (с C++17) |
template< class InputIt > void insert( InputIt first, InputIt last ); | (7) | |
void insert( std::initializer_list<value_type> ilist ); | (8) | (с C++11) |
insert_return_type insert( node_type&& nh ); | (9) | (с C++17) |
iterator insert( const_iterator pos, node_type&& nh ); | (10) | (с C++17) |
Вставляет элемент(ы) в контейнер, если в контейнере ещё нет элемента с эквивалентным ключом.
value.emplace(std::forward<P>(value)) и участвует в разрешении перегрузки только если std::is_constructible<value_type, P&&>::value == true.value в позицию, как можно ближе к позиции, предшествующей pos.emplace_hint(hint, std::forward<P>(value)) и участвует в разрешении перегрузки только если std::is_constructible<value_type, P&&>::value == true.[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, логарифмическая по размеру контейнера в противном случае.Примечания
Вставка с подсказкой (4-6) не возвращает булево значение, чтобы быть совместимой по сигнатуре с позиционной вставкой в последовательных контейнерах, таких как std::vector::insert. Это позволяет создавать универсальные вставки, такие как std::inserter. Один из способов проверить успех вставки с подсказкой — сравнить size() до и после.
Пример
#include <iomanip>
#include <iostream>
#include <map>
#include <string>
using namespace std::literals;
template<typename It>
void print_insertion_status(It it, bool success)
{
std::cout << "Insertion of " << it->first
<< (success ? " succeeded\n" : " failed\n");
}
int main()
{
std::map<std::string, float> heights;
// Overload 3: insert from rvalue reference
const auto [it_hinata, success] = heights.insert({"Hinata"s, 162.8});
print_insertion_status(it_hinata, success);
{
// Overload 1: insert from lvalue reference
const auto [it, success2] = heights.insert(*it_hinata);
print_insertion_status(it, success2);
}
{
// Overload 2: insert via forwarding to emplace
const auto [it, success] = heights.insert(std::pair{"Kageyama", 180.6});
print_insertion_status(it, success);
}
{
// Overload 6: insert from rvalue reference with positional hint
const std::size_t n = std::size(heights);
const auto it = heights.insert(it_hinata, {"Azumane"s, 184.7});
print_insertion_status(it, std::size(heights) != n);
}
{
// Overload 4: insert from lvalue reference with positional hint
const std::size_t n = std::size(heights);
const auto it = heights.insert(it_hinata, *it_hinata);
print_insertion_status(it, std::size(heights) != n);
}
{
// Overload 5: insert via forwarding to emplace with positional hint
const std::size_t n = std::size(heights);
const auto it = heights.insert(it_hinata, std::pair{"Tsukishima", 188.3});
print_insertion_status(it, std::size(heights) != n);
}
auto node_hinata = heights.extract(it_hinata);
std::map<std::string, float> heights2;
// Overload 7: insert from iterator range
heights2.insert(std::begin(heights), std::end(heights));
// Overload 8: insert from initializer_list
heights2.insert({{"Kozume"s, 169.2}, {"Kuroo", 187.7}});
// Overload 9: insert node
const auto status = heights2.insert(std::move(node_hinata));
print_insertion_status(status.position, status.inserted);
node_hinata = heights2.extract(status.position);
{
// Overload 10: insert node with positional hint
const std::size_t n = std::size(heights2);
const auto it = heights2.insert(std::begin(heights2), std::move(node_hinata));
print_insertion_status(it, std::size(heights2) != n);
}
// Print resulting map
std::cout << std::left << '\n';
for (const auto& [name, height] : heights2)
std::cout << std::setw(10) << name << " | " << height << "cm\n";
}Вывод:
Insertion of Hinata succeeded Insertion of Hinata failed Insertion of Kageyama succeeded Insertion of Azumane succeeded Insertion of Hinata failed Insertion of Tsukishima succeeded Insertion of Hinata succeeded Insertion of Hinata succeeded Azumane | 184.7cm Hinata | 162.8cm Kageyama | 180.6cm Kozume | 169.2cm Kuroo | 187.7cm Tsukishima | 188.3cm
Отчёты об ошибках
Следующие отчёты об ошибках, изменяющие поведение, были применены ретроактивно к ранее опубликованным стандартам C++.
| DR | Применено к | Поведение, как опубликовано | Правильное поведение |
|---|---|---|---|
| LWG 233 | C++98 |
pos была просто подсказкой, она могла быть полностью проигнорирована | вставка должна быть как можно ближе к позиции перед pos |
| LWG 264 | C++98 | сложность перегрузки (7) должна была быть линейной, если диапазон [first, last) отсортирован согласно Compare | линейное требование удалено в этом особом случае |
| LWG 316 | C++98 | в возвращаемом значении перегрузки (1) не было указано, какое bool значение указывает на успешную вставку | успех показан значением true |
| LWG 2005 | C++11 | перегрузки (2,5) были плохо описаны | улучшено описание |
См. также
|
(C++11) | создаёт элемент на месте (общедоступный член-функция) |
|
(C++11) | создаёт элементы на месте с помощью подсказки (общедоступный член-функция) |
|
(C++17) | вставляет элемент или присваивает текущему элементу, если ключ уже существует (общедоступный член-функция) |
создаёт std::insert_iterator типа, определяемого из аргумента (шаблон функции) |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/w/cpp/container/map/insert