Namespaces
Variants

std::unordered_map<Key,T,Hash,KeyEqual,Allocator>:: operator[]

From cppreference.net

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

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

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-initialized .
-
value_type должен быть EmplaceConstructible из std:: piecewise_construct , std:: forward_as_tuple ( std :: move ( key ) ) , std:: tuple <> ( ) . При использовании стандартного аллокатора это означает, что key_type должен быть MoveConstructible и mapped_type должен быть DefaultConstructible .
3) Вставляет объект value_type , созданный на месте, если нет ключа, который прозрачно сравнивается эквивалентно со значением x .
Эквивалентно return this - > try_emplace ( std:: forward < K > ( x ) ) . first - > second ; . Данная перегрузка участвует в разрешении перегрузки только если Hash и KeyEqual являются прозрачными . Предполагается, что такой Hash может быть вызван с типами K и Key , а KeyEqual является прозрачным, что в совокупности позволяет вызывать эту функцию без создания экземпляра Key .

Если после операции новое количество элементов становится больше, чем старое max_load_factor() * bucket_count() происходит рехэширование.
Если происходит рехэширование (из-за вставки), все итераторы становятся недействительными. В противном случае (если рехэширования не происходит) итераторы остаются действительными.

Содержание

Параметры

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 <unordered_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::unordered_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::unordered_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'

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

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