Namespaces
Variants

std::map<Key,T,Compare,Allocator>:: operator[]

From cppreference.net

T & operator [ ] ( const Key & key ) ;
(1)
T & operator [ ] ( Key && key ) ;
(2) (начиная с C++11)
template < class K >
T & operator [ ] ( K && x ) ;
(3) (начиная с C++26)

Возвращает ссылку на значение, которое сопоставлено с ключом, эквивалентным key или x соответственно, выполняя вставку, если такой ключ еще не существует.

1) Вставляет value_type ( key, T ( ) ) если ключ не существует.
-
key_type должен удовлетворять требованиям CopyConstructible .
-
mapped_type должен удовлетворять требованиям CopyConstructible и DefaultConstructible .
Если вставка выполняется, отображенное значение инициализируется значением (конструируется по умолчанию для типов классов, инициализируется нулями в остальных случаях) и возвращается ссылка на него.
(до C++11)
1) Вставляет объект value_type , сконструированный на месте из std:: piecewise_construct , std:: forward_as_tuple ( key ) , std:: tuple <> ( ) , если ключ не существует.
Эквивалентно return this - > try_emplace ( key ) . first - > second ; . (начиная с C++17) При использовании аллокатора по умолчанию это приводит к тому, что ключ копируется из key , а сопоставленное значение инициализируется значением по умолчанию .
-
value_type должен быть EmplaceConstructible из std:: piecewise_construct , std:: forward_as_tuple ( key ) , std:: tuple <> ( ) . При использовании аллокатора по умолчанию это означает, что key_type должен быть CopyConstructible и mapped_type должен быть DefaultConstructible .
2) Вставляет объект value_type , сконструированный на месте из std:: piecewise_construct , std:: forward_as_tuple ( std :: move ( key ) ) , std:: tuple <> ( ) , если ключ не существует.
Эквивалентно return this - > try_emplace ( std :: move ( key ) ) . first - > second ; . (начиная с C++17)
При использовании аллокатора по умолчанию это приводит к перемещающему конструированию ключа из key и инициализации значением отображаемого значения.
-
value_type должен быть EmplaceConstructible из std:: piecewise_construct , std:: forward_as_tuple ( std :: move ( key ) ) , std:: tuple <> ( ) . При использовании аллокатора по умолчанию это означает, что key_type должен быть MoveConstructible и mapped_type должен быть DefaultConstructible .
(начиная с C++11)
3) Вставляет объект value_type , созданный на месте, если нет ключа, который прозрачно сравнивается эквивалентно со значением x .
Эквивалентно return this - > try_emplace ( std:: forward < K > ( x ) ) . first - > second ; . Эта перегрузка участвует в разрешении перегрузки только если Compare является прозрачным . Это позволяет вызывать данную функцию без создания экземпляра Key .

Никакие итераторы или ссылки не инвалидируются.

Содержание

Параметры

key - ключ элемента для поиска
x - значение любого типа, которое можно прозрачно сравнивать с ключом

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

1,2) Ссылка на отображаемое значение нового элемента, если элемент с ключом key не существовал. В противном случае — ссылка на отображаемое значение существующего элемента, чей ключ эквивалентен key .
3) Ссылка на отображаемое значение нового элемента, если элемент с ключом, эквивалентным значению x не существовал. В противном случае - ссылка на отображаемое значение существующего элемента, чей ключ эквивалентен x .

Исключения

Если любое операция выбрасывает исключение, вставка не имеет эффекта.

Сложность

Логарифмическая от размера контейнера.

Примечания

В опубликованных стандартах C++11 и C++14 эта функция требовала, чтобы тип mapped_type был DefaultInsertable , а тип key_type был CopyInsertable или MoveInsertable для вставки в * this . Эта спецификация содержала дефект и была исправлена проблемой LWG 2469 , а приведенное выше описание включает резолюцию этой проблемы.

Однако известно, что одна из реализаций (libc++) создаёт объекты key_type и mapped_type через два отдельных вызова аллокатора construct() , что, возможно, требуется опубликованными стандартами, вместо размещения объекта value_type .

operator [ ] является неконстантным, поскольку он вставляет ключ, если он не существует. Если такое поведение нежелательно или если контейнер const , можно использовать at .

insert_or_assign возвращает больше информации, чем operator [ ] и не требует конструируемости по умолчанию для типа значения.

(since C++17)
Feature-test macro Value Std Feature
__cpp_lib_associative_heterogeneous_insertion 202311L (C++26) Гетерогенные перегрузки для оставшихся функций-членов в упорядоченных и неупорядоченных ассоциативных контейнерах . ( 3 )

Пример

#include <iostream>
#include <string>
#include <map>
void println(auto const comment, auto const& map)
{
    std::cout << comment << '{';
    for (const auto& pair : map)
        std::cout << '{' << pair.first << ": " << pair.second << '}';
    std::cout << "}\n";
}
int main()
{
    std::map<char, int> letter_counts{{'a', 27}, {'b', 3}, {'c', 1}};
    println("letter_counts initially contains: ", letter_counts);
    letter_counts['b'] = 42; // обновляет существующее значение
    letter_counts['x'] = 9;  // вставляет новое значение
    println("after modifications it contains: ", letter_counts);
    // подсчитывает количество вхождений каждого слова
    // (первый вызов operator[] инициализирует счетчик нулем)
    std::map<std::string, int>  word_map;
    for (const auto& w : {"this", "sentence", "is", "not", "a", "sentence",
                          "this", "sentence", "is", "a", "hoax"})
        ++word_map[w];
    word_map["that"]; // просто вставляет пару {"that", 0}
    for (const auto& [word, count] : word_map)
        std::cout << count << " occurrence(s) of word '" << word << "'\n";
}

Вывод:

letter_counts initially contains: {{a: 27}{b: 3}{c: 1}}
after modifications it contains: {{a: 27}{b: 42}{c: 1}{x: 9}}
2 occurrence(s) of word 'a'
1 occurrence(s) of word 'hoax'
2 occurrence(s) of word 'is'
1 occurrence(s) of word 'not'
3 occurrence(s) of word 'sentence'
0 occurrence(s) of word 'that'
2 occurrence(s) of word 'this'

Отчеты о дефектах

Следующие отчеты об изменениях поведения, влияющие на дефекты, были применены ретроактивно к ранее опубликованным стандартам C++.

DR Применяется к Поведение в опубликованной версии Корректное поведение
LWG 334 C++98 эффект перегрузки (1) просто возвращал
( * ( ( insert ( std:: make_pair ( x, T ( ) ) ) ) . first ) ) . second
предоставило собственное
описание вместо этого

Смотрите также

доступ к указанному элементу с проверкой границ
(public member function)
вставляет элемент или присваивает текущему элементу, если ключ уже существует
(public member function)
вставляет на месте, если ключ не существует, ничего не делает, если ключ существует
(public member function)