Spec-Zone.ru › C++

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)
iterator insert( iterator pos, const value_type& value );
(4) (до 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)

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

1-3) Вставляет value.
Перегрузка (2) эквивалентна emplace(std::forward<P>(value)) и участвует в разрешении перегрузки только в том случае, если std::is_constructible<value_type, P&&>::value == true.
4-6) Вставляет value в позицию, максимально близкую к позиции непосредственно перед pos.
Перегрузка (5) эквивалентна emplace_hint(hint, std::forward<P>(value)) и участвует в разрешении перегрузки только в том случае, если std::is_constructible<value_type, P&&>::value == true.
7) Вставляет элементы из диапазона [first, last). Если несколько элементов диапазона имеют ключи, сравниваемые как эквивалентные, не указано, какой именно элемент будет вставлен (ожидает рассмотрения LWG2844).
8) Вставляет элементы из списка инициализации ilist. Если несколько элементов диапазона имеют ключи, сравниваемые как эквивалентные, не указано, какой именно элемент будет вставлен (ожидает рассмотрения LWG2844).
9) Если nh — пустой дескриптор узла, ничего не делает. В противном случае вставляет в контейнер элемент, которым владеет nh, если в контейнере еще нет элемента с ключом, эквивалентным nh.key(). Поведение не определено, если nh не пуст и get_allocator() != nh.get_allocator().
10) Если nh — пустой дескриптор узла, ничего не делает и возвращает итератор end. В противном случае вставляет в контейнер элемент, которым владеет nh, если в контейнере еще нет элемента с ключом, эквивалентным nh.key(), и возвращает итератор, указывающий на элемент с ключом, эквивалентным nh.key() (независимо от того, удалась вставка или нет). Если вставка успешна, nh перемещается, в противном случае он сохраняет владение элементом. Элемент вставляется в позицию, максимально близкую к позиции непосредственно перед pos. Поведение не определено, если nh не пуст и get_allocator() != nh.get_allocator().

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

Параметры

pos - итератор на позицию, перед которой будет вставлен новый элемент
value - значение вставляемого элемента
first, last - пара итераторов, определяющая диапазон вставляемых элементов
ilist - список инициализации, из которого вставляются значения
nh - совместимый дескриптор узла
Требования к типам
-InputIt должен удовлетворять требованиям LegacyInputIterator.

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

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

Исключения

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

Сложность

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

См. также

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

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

Spec-Zone.ru

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