跳到主要内容

std::unordered_map operator[] 方法

// (1) Non const version only
T& operator[]( const Key& key );

// (2) Non const version only
T& operator[]( Key&& key );

返回一个引用,该引用指向与 key 等效的键所映射的值,如果该键不存在,则执行插入操作。

  • (1) 如果键不存在,则通过 std::piecewise_constructstd::forward_as_tuple(key)std::tuple<>() 原位构造一个 value_type 对象。此函数等效于 return this->try_emplace(key).first->second;。当使用默认分配器时,这将导致键从 key 复制构造,映射值进行值初始化。

    类型要求

  • (2) 如果键不存在,则通过 std::piecewise_constructstd::forward_as_tuple(std::move(key))std::tuple<>() 原位构造一个 value_type 对象。此函数等效于 return this->try_emplace(std::move(key)).first->second;。当使用默认分配器时,这将导致键从 key 移动构造,映射值进行值初始化。

    类型要求

失效

如果发生插入操作并导致容器进行 rehash,则所有迭代器都会失效。

否则,迭代器不受影响。引用也不会失效。

仅当新元素数量大于 max_load_factor() * bucket_count() 时,才会发生重新哈希。

参数

  • key - 要查找的元素的键

返回值

如果不存在具有 key 的元素,则为新元素的映射值提供的引用。

否则,为具有与 key 等效的键的现有元素提供的映射值引用。

复杂度

平均情况,常数 - O(1)
最坏情况下,与容器的大小呈线性关系 - O(size())

异常

如果任何操作抛出异常,则插入无效。

备注

重要

operator[] 是非 const 的,因为它会在键不存在时插入该键。
如果此行为不理想,或者容器是 const 的,则可以使用 at()

在已发布的 C++11 和 C++14 标准中,此函数被指定需要 mapped_typeDefaultInsertablekey_typeCopyInsertableMoveInsertable*this。此规范存在缺陷,已通过 LWG 2469 修复,上述描述已纳入该问题的解决方案。

然而,一种实现(libc++)已知是通过两个独立的分配器 construct() 调用来构造 key_typemapped_type 对象,这与其说是原位构造 value_type 对象,不如说是按已发布的标准所要求的。这与标准中描述的有所不同。

insert_or_assign() 返回的信息比 operator[] 多,并且不需要映射类型的默认可构造性。

示例

Main.cpp
#include <iostream>
#include <string>
#include <unordered_map>

auto print = [](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}};
print("letter_counts initially contains: ", letter_counts);

letter_counts['b'] = 42; // updates an existing value
letter_counts['x'] = 9; // inserts a new value

print("after modifications it contains: ", letter_counts);

// count the number of occurrences of each word
// (the first call to operator[] initialized the counter with zero)
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"]; // just inserts the pair {"that", 0}

for (const auto &[word, count] : word_map) {
std::cout << count << " occurrences 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 occurrences of word 'a'
1 occurrences of word 'hoax'
2 occurrences of word 'is'
1 occurrences of word 'not'
3 occurrences of word 'sentence'
0 occurrences of word 'that'
2 occurrences of word 'this'
本文源自此 CppReference 页面。为改进或编辑偏好可能对其进行了修改。点击“编辑此页面”以查看对本文档所做的所有更改。
悬停查看原始许可证。

std::unordered_map operator[] 方法

// (1) Non const version only
T& operator[]( const Key& key );

// (2) Non const version only
T& operator[]( Key&& key );

返回一个引用,该引用指向与 key 等效的键所映射的值,如果该键不存在,则执行插入操作。

  • (1) 如果键不存在,则通过 std::piecewise_constructstd::forward_as_tuple(key)std::tuple<>() 原位构造一个 value_type 对象。此函数等效于 return this->try_emplace(key).first->second;。当使用默认分配器时,这将导致键从 key 复制构造,映射值进行值初始化。

    类型要求

  • (2) 如果键不存在,则通过 std::piecewise_constructstd::forward_as_tuple(std::move(key))std::tuple<>() 原位构造一个 value_type 对象。此函数等效于 return this->try_emplace(std::move(key)).first->second;。当使用默认分配器时,这将导致键从 key 移动构造,映射值进行值初始化。

    类型要求

失效

如果发生插入操作并导致容器进行 rehash,则所有迭代器都会失效。

否则,迭代器不受影响。引用也不会失效。

仅当新元素数量大于 max_load_factor() * bucket_count() 时,才会发生重新哈希。

参数

  • key - 要查找的元素的键

返回值

如果不存在具有 key 的元素,则为新元素的映射值提供的引用。

否则,为具有与 key 等效的键的现有元素提供的映射值引用。

复杂度

平均情况,常数 - O(1)
最坏情况下,与容器的大小呈线性关系 - O(size())

异常

如果任何操作抛出异常,则插入无效。

备注

重要

operator[] 是非 const 的,因为它会在键不存在时插入该键。
如果此行为不理想,或者容器是 const 的,则可以使用 at()

在已发布的 C++11 和 C++14 标准中,此函数被指定需要 mapped_typeDefaultInsertablekey_typeCopyInsertableMoveInsertable*this。此规范存在缺陷,已通过 LWG 2469 修复,上述描述已纳入该问题的解决方案。

然而,一种实现(libc++)已知是通过两个独立的分配器 construct() 调用来构造 key_typemapped_type 对象,这与其说是原位构造 value_type 对象,不如说是按已发布的标准所要求的。这与标准中描述的有所不同。

insert_or_assign() 返回的信息比 operator[] 多,并且不需要映射类型的默认可构造性。

示例

Main.cpp
#include <iostream>
#include <string>
#include <unordered_map>

auto print = [](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}};
print("letter_counts initially contains: ", letter_counts);

letter_counts['b'] = 42; // updates an existing value
letter_counts['x'] = 9; // inserts a new value

print("after modifications it contains: ", letter_counts);

// count the number of occurrences of each word
// (the first call to operator[] initialized the counter with zero)
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"]; // just inserts the pair {"that", 0}

for (const auto &[word, count] : word_map) {
std::cout << count << " occurrences 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 occurrences of word 'a'
1 occurrences of word 'hoax'
2 occurrences of word 'is'
1 occurrences of word 'not'
3 occurrences of word 'sentence'
0 occurrences of word 'that'
2 occurrences of word 'this'
本文源自此 CppReference 页面。为改进或编辑偏好可能对其进行了修改。点击“编辑此页面”以查看对本文档所做的所有更改。
悬停查看原始许可证。