std::unordered_map::unordered_map

本文详细介绍了C++标准库中unordered_map容器的各种构造函数用法,包括默认构造、范围构造、拷贝构造及移动构造等,并给出了具体的示例代码。

转自:http://en.cppreference.com/w/cpp/container/unordered_map/unordered_map

explicit unordered_map( size_type bucket_count = /*implementation-defined*/,

                        const Hash& hash = Hash(),
                        const KeyEqual& equal = KeyEqual(),
                        const Allocator& alloc = Allocator() );
unordered_map( size_type bucket_count,
                        const Allocator& alloc = Allocator() );
unordered_map( size_type bucket_count,
                        const Hash& hash,

                        const Allocator& alloc = Allocator() );
(1)(since C++11)


(since C++14)
     
explicit unordered_map( const Allocator& alloc );
(1)(since C++11)
     
template< class InputIt >

unordered_map( InputIt first, InputIt last,
               size_type bucket_count = /*implementation-defined*/,
               const Hash& hash = Hash(),
               const KeyEqual& equal = KeyEqual(),
               const Allocator& alloc = Allocator() );
template< class InputIt >
unordered_map( InputIt first, InputIt last,
               size_type bucket_count,
               const Allocator& alloc = Allocator() );
template< class InputIt >
unordered_map( InputIt first, InputIt last,
               size_type bucket_count,
               const Hash& hash,

               const Allocator& alloc = Allocator() );
(2)(since C++11)


(since C++14)
     
unordered_map( const unordered_map& other );
(3)(since C++11)
     
unordered_map( const unordered_map& other, const Allocator& alloc );
(3)(since C++11)
     
unordered_map( unordered_map&& other );
(4)(since C++11)
     
unordered_map( unordered_map&& other, const Allocator& alloc );
(4)(since C++11)
     
unordered_map( std::initializer_list<value_type> init,

               size_type bucket_count = /*implementation-defined*/,
               const Hash& hash = Hash(),
               const KeyEqual& equal = KeyEqual(),
               const Allocator& alloc = Allocator() );
unordered_map( std::initializer_list<value_type> init,
               size_type bucket_count,
               const Allocator& alloc = Allocator() );
unordered_map( std::initializer_list<value_type> init,
               size_type bucket_count,
               const Hash& hash,

               const Allocator& alloc = Allocator() );
(5)(since C++11)


(since C++14)
     

Constructs new container from a variety of data sources. Optionally uses user supplied bucket_count as a minimal number of buckets to create, hash as the hash function, equal as the function to compare keys and alloc as the allocator.

1) default constructor. Constructs empty container.

2) constructs the container with the contents of the range [first, last).

3) copy constructor. Constructs the container with the copy of the contents of other. If alloc is not provided, allocator is obtained by calling std::allocator_traits<allocator_type>::select_on_copy_construction(other).

4) move constructor. Constructs the container with the contents of other using move semantics. If alloc is not provided, allocator is obtained by move-construction from the allocator belonging to other.

5) constructs the container with the contents of the initializer list init.

Parameters

alloc-allocator to use for all memory allocations of this container
bucket_count-minimal number of buckets to use on initialization. If it is not specified, implementation-defined default value is used
hash-hash function to use
equal-comparison function to use for all key comparisons of this container
first, last-the range to copy the elements from
other-another container to be used as source to initialize the elements of the container with
init-initializer list to initialize the elements of the container with
Type requirements
-
InputIt must meet the requirements of InputIterator.

Complexity

1) constant

2) linear in distance between first and last

3) linear in size of other

4) constant. If alloc is given and alloc != other.get_allocator(), then linear.

5) linear in size of init

Example

#include <unordered_map>
#include <vector>
#include <bitset>
#include <string>
#include <utility>
 
struct Key {
    std::string first;
    std::string second;
};
 
struct KeyHash {
 std::size_t operator()(const Key& k) const
 {
     return std::hash<std::string>()(k.first) ^
            (std::hash<std::string>()(k.second) << 1);
 }
};
 
struct KeyEqual {
 bool operator()(const Key& lhs, const Key& rhs) const
 {
    return lhs.first == rhs.first && lhs.second == rhs.second;
 }
};
 
int main()
{
    // default constructor: empty map
    std::unordered_map<std::string, std::string> m1;
 
    // list constructor
    std::unordered_map<int, std::string> m2 =
    {
        {1, "foo"},
        {3, "bar"},
        {2, "baz"},
    };
 
    // copy constructor
    std::unordered_map<int, std::string> m3 = m2;
 
    // move constructor
    std::unordered_map<int, std::string> m4 = std::move(m2);
 
    // range constructor
    std::vector<std::pair<std::bitset<8>, int>> v = { {0x12, 1}, {0x01,-1} };
    std::unordered_map<std::bitset<8>, double> m5(v.begin(), v.end());
 
    // constructor for a custom type
    std::unordered_map<Key, std::string, KeyHash, KeyEqual> m6 = {
            { {"John", "Doe"}, "example"},
            { {"Mary", "Sue"}, "another"}
    };
}


See also

 
assigns values to the container 
(public member function)

<think>我们被要求比较std::unordered_mapstd::map(通常基于红黑树实现)。两者都是关联容器,但有不同的特性和性能特征。 我们将从以下几个方面进行对比: 1. 内部实现 2. 时间复杂度 3. 元素顺序 4. 内存使用 5. 迭代器有效性 6. 使用场景 然后给出代码示例说明基本操作和注意事项。 </think>### `std::unordered_map` vs `std::map` 全面对比 在 C++ 中,`std::unordered_map` 和 `std::map` 都是关联容器,但在实现、性能特性和使用场景上有显著差异: --- #### 1. **底层实现** | 容器 | 实现原理 | 结构特点 | |--------------------|--------------------------|--------------------------| | `std::map` | **红黑树**(自平衡二叉搜索树) | 节点存储键值对 + 左右子节点指针 | | `std::unordered_map` | **哈希表**(桶数组 + 链表/红黑树) | 数组存储桶头指针 + 链表存储冲突元素 | ```cpp // map: 树状结构示意 struct TreeNode { std::pair<Key, Value> data; TreeNode* left; TreeNode* right; // ... 平衡信息 }; // unordered_map: 哈希桶结构示意 std::vector<Bucket> buckets; // 桶数组 struct Node { std::pair<Key, Value> data; Node* next; // 冲突链表 }; ``` --- #### 2. **时间复杂度对比** | 操作 | `std::map` | `std::unordered_map` | |-------------------|-----------------|----------------------| | 插入 (`insert`) | O(log n) | **O(1)** 平均 / O(n) 最坏 | | 查找 (`find`) | O(log n) | **O(1)** 平均 / O(n) 最坏 | | 删除 (`erase`) | O(log n) | **O(1)** 平均 / O(n) 最坏 | | 范围遍历 | **O(n)** | O(n) 但缓存不友好 | | 有序遍历 | **有序迭代** | 无序 | --- #### 3. **元素顺序特性** | 特性 | `std::map` | `std::unordered_map` | |-----------------------|--------------------------------|--------------------------------| | 键排序 | 严格按**键升序**(默认`<`比较) | **无任何顺序保证** | | 迭代顺序 | 稳定的中序遍历顺序 | 依赖哈希函数和桶布局 | | 自定义排序 | 支持自定义比较器 | 不支持 | ```cpp // map 保证有序输出 std::map<int, std::string> m{{3, "C"}, {1, "A"}, {2, "B"}}; for (auto& [k, v] : m) std::cout << k; // 输出: 1 2 3 // unordered_map 无序输出 std::unordered_map<int, std::string> um{{3, "C"}, {1, "A"}, {2, "B"}}; for (auto& [k, v] : um) std::cout << k; // 可能输出: 2 1 3 或其他顺序 ``` --- #### 4. **内存与性能考量** | 因素 | `std::map` | `std::unordered_map` | |---------------------|------------------------------|-------------------------------| | 内存开销 | 每个节点额外 2 指针 + 平衡信息 | 桶数组 + 每个元素链表指针 | | 缓存友好度 | 较差(节点分散) | **更差**(哈希冲突时跳跃访问) | | 哈希函数要求 | 不需要 | 需要高质量哈希函数 (`std::hash`) | | 自定义哈希支持 | 不支持 | 支持自定义哈希器 | --- #### 5. **迭代器有效性** | 操作 | `std::map` | `std::unordered_map` | |---------------------|----------------------------------|----------------------------------| | 插入元素 | **不失效**(除被修改节点) | 可能导致**全部重哈希**(桶扩容) | | 删除元素 | 仅使被删元素迭代器失效 | 仅使被删元素迭代器失效 | --- ### **关键选择指南** 1. 使用 `std::map` 当: - 需要**有序遍历**或**范围查询**(如 `lower_bound`) - 键类型无高效哈希函数 - 避免哈希冲突导致的性能波动 - 内存限制较小(哈希表桶数组有最小开销) 2. 使用 `std::unordered_map` 当: - 需要**O(1)平均访问性能** - 不关心元素顺序 - 有高质量哈希函数(或能自定义) - 内存充足(哈希表需要额外 20-50% 空间) --- ### **自定义键示例** ```cpp // 自定义键类型(需支持map比较或unordered_map哈希) struct Point { int x, y; bool operator==(const Point& p) const { return x == p.x && y == p.y; } }; // 为map定义比较器 struct PointCompare { bool operator()(const Point& a, const Point& b) const { return std::tie(a.x, a.y) < std::tie(b.x, b.y); } }; std::map<Point, std::string, PointCompare> pointMap; // 为unordered_map定义哈希器 struct PointHash { size_t operator()(const Point& p) const { return std::hash<int>()(p.x) ^ (std::hash<int>()(p.y) << 1); } }; std::unordered_map<Point, std::string, PointHash> pointUMap; ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值