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)
(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)

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

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 — это пустая ручка узла, ничего не делает и возвращает итератор конца. В противном случае, вставляет элемент, принадлежащий 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) Итератор конца, если 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/w/cpp/container/map/insert

Spec-Zone.ru

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