STL-unordered

This commit is contained in:
e2hang
2025-08-13 15:39:44 +08:00
parent 6ca2ae6356
commit 120db9b163
2 changed files with 646 additions and 0 deletions

View File

@@ -0,0 +1,321 @@
<h1>C++ STL unordered_map容器用法详解</h1>
<div class="pre-next-page clearfix">&nbsp;</div>
<div id="arc-body"><a href='/cplus/' target='_blank'>C++</a> <a href='/stl/' target='_blank'>STL</a> 标准库中提供有 4 种无序关联式容器,本节先讲解<span style="color:#008000;"> unordered_map 容器</span>。<br />
<br />
unordered_map 容器,直译过来就是&quot;无序 map 容器&quot;的意思。所谓&ldquo;无序&rdquo;,指的是 unordered_map 容器不会像 map 容器那样对存储的数据进行排序。换句话说unordered_map 容器和 map 容器仅有一点不同,即 map 容器中存储的数据是有序的,而 unordered_map 容器中是无序的。<br />
<blockquote>
<p>
对于已经学过 map 容器的读者,可以将 unordered_map 容器等价为无序的 map 容器。</p>
</blockquote>
具体来讲unordered_map 容器和 map 容器一样以键值对pair类型的形式存储数据存储的各个键值对的键互不相同且不允许被修改。但由于 unordered_map 容器底层采用的是哈希表存储结构,该结构本身不具有对数据的排序功能,所以此容器内部不会自行对存储的键值对进行排序。<br />
<br />
值得一提的是unordered_map 容器在<code>&lt;unordered_map&gt;</code>头文件中,并位于 std 命名空间中。因此,如果想使用该容器,代码中应包含如下语句:<br />
<pre class="cpp">
#include &lt;unordered_map&gt;
using namespace std;</pre>
<blockquote>
<p>
注意,第二行代码不是必需的,但如果不用,则后续程序中在使用此容器时,需手动注明 std 命名空间(强烈建议初学者使用)。</p>
</blockquote>
unordered_map 容器模板的定义如下所示:
<pre class="cpp">
template &lt; class Key,//键值对中键的类型
class T,//键值对中值的类型
class Hash = hash&lt;Key&gt;,//容器内存储键值对所用的哈希函数
class Pred = equal_to&lt;Key&gt;,//判断各个键值对键相同的规则
class Alloc = allocator&lt; pair&lt;const Key,T&gt; &gt; // 指定分配器对象的类型
&gt; class unordered_map;</pre>
以上 5 个参数中,必须显式给前 2 个参数传值,并且除特殊情况外,最多只需要使用前 4 个参数,各自的含义和功能如表 1 所示。<br />
<br />
<table>
<caption>
表 1 unordered_map 容器模板类的常用参数</caption>
<tbody>
<tr>
<th>
参数</th>
<th>
含义</th>
</tr>
<tr>
<td>
&lt;key,T&gt;</td>
<td>
前 2 个参数分别用于确定键值对中键和值的类型,也就是存储键值对的类型。</td>
</tr>
<tr>
<td>
Hash = hash&lt;Key&gt;</td>
<td>
用于指明容器在存储各个键值对时要使用的哈希函数,默认使用 STL 标准库提供的 hash&lt;key&gt; 哈希函数。注意,默认哈希函数只适用于基本数据类型(包括 string 类型),而不适用于自定义的结构体或者类。</td>
</tr>
<tr>
<td>
Pred = equal_to&lt;Key&gt;</td>
<td>
要知道unordered_map 容器中存储的各个键值对的键是不能相等的,而判断是否相等的规则,就由此参数指定。默认情况下,使用 STL 标准库中提供的 equal_to&lt;key&gt; 规则,该规则仅支持可直接用 == 运算符做比较的数据类型。</td>
</tr>
</tbody>
</table>
<blockquote>
<p>
总的来说,当无序容器中存储键值对的键为自定义类型时,默认的哈希函数 hash<key> 以及比较函数 equal_to<key> 将不再适用,只能自己设计适用该类型的哈希函数和比较函数,并显式传递给 Hash 参数和 Pred 参数。至于如何实现自定义,后续章节会做详细讲解。</key></key></p>
</blockquote>
<h2>
创建C++ unordered_map容器的方法</h2>
常见的创建 unordered_map 容器的方法有以下几种。<br />
<br />
1) 通过调用 unordered_map 模板类的默认构造函数,可以创建空的 unordered_map 容器。比如:
<pre class="cpp">
std::unordered_map&lt;std::string, std::string&gt; umap;</pre>
由此,就创建好了一个可存储 &lt;string,string&gt; 类型键值对的 unordered_map 容器。<br />
<br />
2) 当然,在创建 unordered_map 容器的同时,可以完成初始化操作。比如:
<pre class="cpp">
std::unordered_map&lt;std::string, std::string&gt; umap{
{&quot;<a href='/python/' target='_blank'>Python</a>教程&quot;,&quot;http://c.biancheng.net/python/&quot;},
{&quot;Java教程&quot;,&quot;http://c.biancheng.net/java/&quot;},
{&quot;Linux教程&quot;,&quot;http://c.biancheng.net/linux/&quot;} };</pre>
通过此方法创建的 umap 容器中,就包含有 3 个键值对元素。<br />
<br />
3) 另外,还可以调用 unordered_map 模板中提供的复制(拷贝)构造函数,将现有 unordered_map 容器中存储的键值对,复制给新建 unordered_map 容器。<br />
<br />
例如,在第二种方式创建好 umap 容器的基础上,再创建并初始化一个 umap2 容器:
<pre class="cpp">
std::unordered_map&lt;std::string, std::string&gt; umap2(umap);</pre>
由此umap2 容器中就包含有 umap 容器中所有的键值对。<br />
<br />
除此之外C++ 11 标准中还向 unordered_map 模板类增加了移动构造函数,即以右值引用的方式将临时 unordered_map 容器中存储的所有键值对,全部复制给新建容器。例如:
<pre class="cpp">
//返回临时 unordered_map 容器的函数
std::unordered_map &lt;std::string, std::string &gt; retUmap(){
std::unordered_map&lt;std::string, std::string&gt;tempUmap{
{&quot;Python教程&quot;,&quot;http://c.biancheng.net/python/&quot;},
{&quot;Java教程&quot;,&quot;http://c.biancheng.net/java/&quot;},
{&quot;Linux教程&quot;,&quot;http://c.biancheng.net/linux/&quot;} };
return tempUmap;
}
//调用移动构造函数,创建 umap2 容器
std::unordered_map&lt;std::string, std::string&gt; umap2(retUmap());</pre>
注意,无论是调用复制构造函数还是拷贝构造函数,必须保证 2 个容器的类型完全相同。<br />
<br />
4) 当然,如果不想全部拷贝,可以使用 unordered_map 类模板提供的迭代器,在现有 unordered_map 容器中选择部分区域内的键值对,为新建 unordered_map 容器初始化。例如:
<pre class="cpp">
//传入 2 个迭代器,
std::unordered_map&lt;std::string, std::string&gt; umap2(++umap.begin(),umap.end());</pre>
通过此方式创建的 umap2 容器,其内部就包含 umap 容器中除第 1 个键值对外的所有其它键值对。<br />
<h2>
C++ unordered_map容器的成员方法</h2>
unordered_map 既可以看做是关联式容器,更属于自成一脉的无序容器。因此在该容器模板类中,既包含一些在学习关联式容器时常见的成员方法,还有一些属于无序容器特有的成员方法。<br />
<br />
表 2 列出了 unordered_map 类模板提供的所有常用的成员方法以及各自的功能。<br />
<br />
<table>
<caption>
表 2 unordered_map类模板成员方法</caption>
<tbody>
<tr>
<th>
成员方法</th>
<th>
功能</th>
</tr>
<tr>
<td>
begin()</td>
<td>
返回指向容器中第一个键值对的正向迭代器。</td>
</tr>
<tr>
<td>
end()&nbsp;</td>
<td>
返回指向容器中最后一个键值对之后位置的正向迭代器。</td>
</tr>
<tr>
<td>
cbegin()</td>
<td>
和 begin() 功能相同,只不过在其基础上增加了 const 属性,即该方法返回的迭代器不能用于修改容器内存储的键值对。</td>
</tr>
<tr>
<td>
cend()</td>
<td>
和 end() 功能相同,只不过在其基础上,增加了 const 属性,即该方法返回的迭代器不能用于修改容器内存储的键值对。</td>
</tr>
<tr>
<td>
empty()</td>
<td>
若容器为空,则返回 true否则 false。</td>
</tr>
<tr>
<td>
size()</td>
<td>
返回当前容器中存有键值对的个数。</td>
</tr>
<tr>
<td>
max_size()</td>
<td>
返回容器所能容纳键值对的最大个数,不同的操作系统,其返回值亦不相同。</td>
</tr>
<tr>
<td>
operator[key]</td>
<td>
该模板类中重载了 [] 运算符,其功能是可以向访问数组中元素那样,只要给定某个键值对的键 key就可以获取该键对应的值。注意如果当前容器中没有以 key 为键的键值对,则其会使用该键向当前容器中插入一个新键值对。</td>
</tr>
<tr>
<td>
at(key)</td>
<td>
返回容器中存储的键 key 对应的值,如果 key 不存在,则会抛出 out_of_range 异常。&nbsp;</td>
</tr>
<tr>
<td>
find(key)</td>
<td>
查找以 key 为键的键值对,如果找到,则返回一个指向该键值对的正向迭代器;反之,则返回一个指向容器中最后一个键值对之后位置的迭代器(如果 end() 方法返回的迭代器)。</td>
</tr>
<tr>
<td>
count(key)</td>
<td>
在容器中查找以 key 键的键值对的个数。</td>
</tr>
<tr>
<td>
equal_range(key)</td>
<td>
返回一个 pair 对象,其包含 2 个迭代器,用于表明当前容器中键为 key 的键值对所在的范围。</td>
</tr>
<tr>
<td>
emplace()</td>
<td>
向容器中添加新键值对,效率比 insert() 方法高。</td>
</tr>
<tr>
<td>
emplace_hint()</td>
<td>
向容器中添加新键值对,效率比 insert() 方法高。</td>
</tr>
<tr>
<td>
insert()&nbsp;</td>
<td>
向容器中添加新键值对。</td>
</tr>
<tr>
<td>
erase()</td>
<td>
删除指定键值对。</td>
</tr>
<tr>
<td>
clear()&nbsp;</td>
<td>
清空容器,即删除容器中存储的所有键值对。</td>
</tr>
<tr>
<td>
swap()</td>
<td>
交换 2 个 unordered_map 容器存储的键值对,前提是必须保证这 2 个容器的类型完全相等。</td>
</tr>
<tr>
<td>
bucket_count()</td>
<td>
返回当前容器底层存储键值对时,使用桶(一个线性链表代表一个桶)的数量。</td>
</tr>
<tr>
<td>
max_bucket_count()</td>
<td>
返回当前系统中unordered_map 容器底层最多可以使用多少桶。</td>
</tr>
<tr>
<td>
bucket_size(n)</td>
<td>
返回第 n 个桶中存储键值对的数量。</td>
</tr>
<tr>
<td>
bucket(key)</td>
<td>
返回以 key 为键的键值对所在桶的编号。</td>
</tr>
<tr>
<td>
load_factor()</td>
<td>
返回 unordered_map 容器中当前的负载因子。负载因子指的是的当前容器中存储键值对的数量size()和使用桶数bucket_count())的比值,即 load_factor() = size() / bucket_count()。</td>
</tr>
<tr>
<td>
max_load_factor()</td>
<td>
返回或者设置当前 unordered_map 容器的负载因子。</td>
</tr>
<tr>
<td>
rehash(n)</td>
<td>
将当前容器底层使用桶的数量设置为 n。</td>
</tr>
<tr>
<td>
reserve()</td>
<td>
将存储桶的数量(也就是 bucket_count() 方法的返回值设置为至少容纳count个元不超过最大负载因子所需的数量并重新整理容器。</td>
</tr>
<tr>
<td>
hash_function()</td>
<td>
返回当前容器使用的哈希函数对象。</td>
</tr>
</tbody>
</table>
<blockquote>
<p>
注意,对于实现互换 2 个相同类型 unordered_map 容器的键值对,除了可以调用该容器模板类中提供的 swap() 成员方法外STL 标准库还提供了同名的 swap() 非成员函数。</p>
</blockquote>
<br />
下面的样例演示了表 2 中部分成员方法的用法:<br />
<pre class="cpp">
#include &lt;iostream&gt;
#include &lt;string&gt;
#include &lt;unordered_map&gt;
using namespace std;
int main()
{
//创建空 umap 容器
unordered_map&lt;string, string&gt; umap;
//向 umap 容器添加新键值对
umap.emplace(&quot;Python教程&quot;, &quot;http://c.biancheng.net/python/&quot;);
umap.emplace(&quot;Java教程&quot;, &quot;http://c.biancheng.net/java/&quot;);
umap.emplace(&quot;Linux教程&quot;, &quot;http://c.biancheng.net/linux/&quot;);
//输出 umap 存储键值对的数量
cout &lt;&lt; &quot;umap size = &quot; &lt;&lt; umap.size() &lt;&lt; endl;
//使用迭代器输出 umap 容器存储的所有键值对
<a href='/view/1811.html' target='_blank'>for</a> (auto iter = umap.begin(); iter != umap.end(); ++iter) {
cout &lt;&lt; iter-&gt;first &lt;&lt; &quot; &quot; &lt;&lt; iter-&gt;second &lt;&lt; endl;
}
return 0;
}</pre>
程序执行结果为:
<p class="info-box">
umap size = 3<br />
Python教程 http://c.biancheng.net/python/<br />
Linux教程 http://c.biancheng.net/linux/<br />
Java教程 http://c.biancheng.net/java/</p>

View File

@@ -0,0 +1,325 @@
<h1>C++ STL unordered_set容器完全攻略</h1>
<div class="pre-next-page clearfix">&nbsp;</div>
<div id="arc-body">我们知道,<a href='/cplus/' target='_blank'>C++</a> 11 为 <a href='/stl/' target='_blank'>STL</a> 标准库增添了 4 种无序(哈希)容器,前面已经对 unordered_map 和 unordered_multimap 容器做了详细的介绍,本节再讲解一种无序容器,即 <span style="color:#008000;">unordered_set</span> 容器。<br />
<br />
unordered_set 容器,可直译为&ldquo;无序 set 容器&rdquo;,即 unordered_set 容器和 set 容器很像,唯一的区别就在于 set 容器会自行对存储的数据进行排序,而 unordered_set 容器不会。<br />
<br />
总的来说unordered_set 容器具有以下几个特性:
<ol>
<li>
不再以键值对的形式存储数据,而是直接存储数据的值;</li>
<li>
容器内部存储的各个元素的值都互不相等,且不能被修改。</li>
<li>
不会对内部存储的数据进行排序(这和该容器底层采用哈希表结构存储数据有关,可阅读《<a href="/view/7235.html" target="_blank">C++ STL无序容器底层实现原理</a>》一文做详细了解);</li>
</ol>
<blockquote>
<p>
对于 unordered_set 容器不以键值对的形式存储数据,读者也可以这样认为,即 unordered_set 存储的都是键和值相等的键值对,为了节省存储空间,该类容器在实际存储时选择只存储每个键值对的值。</p>
</blockquote>
另外,实现 unordered_set 容器的模板类定义在<code>&lt;unordered_set&gt;</code>头文件,并位于 std 命名空间中。这意味着,如果程序中需要使用该类型容器,则首先应该包含如下代码:
<pre class="cpp">
#include &lt;unordered_set&gt;
using namespace std;</pre>
<blockquote>
<p>
注意,第二行代码不是必需的,但如果不用,则程序中只要用到该容器时,必须手动注明 std 命名空间(强烈建议初学者使用)。</p>
</blockquote>
unordered_set 容器的类模板定义如下:
<pre class="cpp">
template &lt; class Key, //容器中存储元素的类型
class Hash = hash&lt;Key&gt;, //确定元素存储位置所用的哈希函数
class Pred = equal_to&lt;Key&gt;, //判断各个元素是否相等所用的函数
class Alloc = allocator&lt;Key&gt; //指定分配器对象的类型
&gt; class unordered_set;</pre>
可以看到,以上 4 个参数中,只有第一个参数没有默认值,这意味着如果我们想创建一个 unordered_set 容器,至少需要手动传递 1 个参数。事实上,在 99% 的实际场景中最多只需要使用前 3 个参数(各自含义如表 1 所示),最后一个参数保持默认值即可。<br />
<br />
<table>
<caption>
表 1 unordered_set模板类定义</caption>
<tbody>
<tr>
<th>
参数</th>
<th>
含义</th>
</tr>
<tr>
<td>
Key</td>
<td>
确定容器存储元素的类型,如果读者将 unordered_set 看做是存储键和值相同的键值对的容器,则此参数则用于确定各个键值对的键和值的类型,因为它们是完全相同的,因此一定是同一数据类型的数据。</td>
</tr>
<tr>
<td>
Hash = hash&lt;Key&gt;</td>
<td>
指定 unordered_set 容器底层存储各个元素时,所使用的哈希函数。需要注意的是,默认哈希函数 hash&lt;Key&gt; 只适用于基本数据类型(包括 string 类型),而不适用于自定义的结构体或者类。</td>
</tr>
<tr>
<td>
Pred = equal_to&lt;Key&gt;</td>
<td>
unordered_set&nbsp;容器内部不能存储相等的元素,而衡量 2 个元素是否相等的标准,取决于该参数指定的函数。 默认情况下,使用 STL 标准库中提供的 equal_to&lt;key&gt; 规则,该规则仅支持可直接用 == 运算符做比较的数据类型。</td>
</tr>
</tbody>
</table>
<blockquote>
<p>
注意,如果 unordered_set 容器中存储的元素为自定义的数据类型,则默认的哈希函数 hash&lt;key&gt; 以及比较函数 equal_to&lt;key&gt; 将不再适用,只能自己设计适用该类型的哈希函数和比较函数,并显式传递给 Hash 参数和 Pred 参数。至于如何实现自定义,后续章节会做详细讲解。</p>
</blockquote>
<h2>
创建C++ unordered_set容器</h2>
前面介绍了如何创建 unordered_map 和 unordered_multimap 容器,值得一提的是,创建它们的所有方式完全适用于 unordereded_set 容器。不过,考虑到一些读者可能尚未学习其它无序容器,因此这里还是讲解一下创建 unordered_set 容器的几种方法。<br />
<br />
1) 通过调用 unordered_set 模板类的默认构造函数,可以创建空的 unordered_set 容器。比如:
<pre class="cpp">
std::unordered_set&lt;std::string&gt; uset;</pre>
<blockquote>
<p>
如果程序已经引入了 std 命名空间,这里可以省略所有的 std::。</p>
</blockquote>
由此,就创建好了一个可存储 string 类型值的 unordered_set 容器,该容器底层采用默认的哈希函数 hash&lt;Key&gt; 和比较函数 equal_to&lt;Key&gt;。<br />
<br />
2) 当然,在创建 unordered_set 容器的同时,可以完成初始化操作。比如:
<pre class="cpp">
std::unordered_set&lt;std::string&gt; uset{ &quot;http://c.biancheng.net/c/&quot;,
&quot;http://c.biancheng.net/java/&quot;,
&quot;http://c.biancheng.net/linux/&quot; };</pre>
通过此方法创建的 uset 容器中,就包含有 3 个 string 类型元素。<br />
<br />
3) 还可以调用 unordered_set 模板中提供的复制(拷贝)构造函数,将现有 unordered_set 容器中存储的元素全部用于为新建 unordered_set 容器初始化。<br />
<br />
例如,在第二种方式创建好 uset 容器的基础上,再创建并初始化一个 uset2 容器:
<pre class="cpp">
std::unordered_set&lt;std::string&gt; uset2(uset);</pre>
由此umap2 容器中就包含有 umap 容器中所有的元素。<br />
<br />
除此之外C++ 11 标准中还向 unordered_set 模板类增加了移动构造函数,即以右值引用的方式,利用临时 unordered_set 容器中存储的所有元素,给新建容器初始化。例如:
<pre class="cpp">
//返回临时 unordered_set 容器的函数
std::unordered_set &lt;std::string&gt; retuset() {
std::unordered_set&lt;std::string&gt; tempuset{ &quot;http://c.biancheng.net/c/&quot;,
&quot;http://c.biancheng.net/java/&quot;,
&quot;http://c.biancheng.net/linux/&quot; };
return tempuset;
}
//调用移动构造函数,创建 uset 容器
std::unordered_set&lt;std::string&gt; uset(retuset());</pre>
<blockquote>
<p>
注意,无论是调用复制构造函数还是拷贝构造函数,必须保证 2 个容器的类型完全相同。</p>
</blockquote>
<br />
4) 当然,如果不想全部拷贝,可以使用 unordered_set 类模板提供的迭代器,在现有 unordered_set 容器中选择部分区域内的元素,为新建 unordered_set 容器初始化。例如:
<pre class="cpp">
//传入 2 个迭代器,
std::unordered_set&lt;std::string&gt; uset2(++uset.begin(),uset.end());</pre>
通过此方式创建的 uset2 容器,其内部就包含 uset 容器中除第 1 个元素外的所有其它元素。<br />
<h2>
C++ unordered_set容器的成员方法</h2>
unordered_set 类模板中,提供了如表 2 所示的成员方法。<br />
<br />
<table>
<caption>
表 2 unordered_set 类模板成员方法</caption>
<tbody>
<tr>
<th>
成员方法</th>
<th>
功能</th>
</tr>
<tr>
<td>
begin()</td>
<td>
返回指向容器中第一个元素的正向迭代器。</td>
</tr>
<tr>
<td>
end();</td>
<td>
返回指向容器中最后一个元素之后位置的正向迭代器。</td>
</tr>
<tr>
<td>
cbegin()</td>
<td>
和 begin() 功能相同,只不过其返回的是 const 类型的正向迭代器。</td>
</tr>
<tr>
<td>
cend()</td>
<td>
和 end() 功能相同,只不过其返回的是 const 类型的正向迭代器。</td>
</tr>
<tr>
<td>
empty()</td>
<td>
若容器为空,则返回 true否则 false。</td>
</tr>
<tr>
<td>
size()</td>
<td>
返回当前容器中存有元素的个数。</td>
</tr>
<tr>
<td>
max_size()</td>
<td>
返回容器所能容纳元素的最大个数,不同的操作系统,其返回值亦不相同。</td>
</tr>
<tr>
<td>
find(key)</td>
<td>
查找以值为 key 的元素,如果找到,则返回一个指向该元素的正向迭代器;反之,则返回一个指向容器中最后一个元素之后位置的迭代器(如果 end() 方法返回的迭代器)。</td>
</tr>
<tr>
<td>
count(key)</td>
<td>
在容器中查找值为 key 的元素的个数。</td>
</tr>
<tr>
<td>
equal_range(key)</td>
<td>
返回一个 pair 对象,其包含 2 个迭代器,用于表明当前容器中值为 key 的元素所在的范围。</td>
</tr>
<tr>
<td>
emplace()</td>
<td>
向容器中添加新元素,效率比 insert() 方法高。</td>
</tr>
<tr>
<td>
emplace_hint()</td>
<td>
向容器中添加新元素,效率比 insert() 方法高。</td>
</tr>
<tr>
<td>
insert()</td>
<td>
向容器中添加新元素。</td>
</tr>
<tr>
<td>
erase()</td>
<td>
删除指定元素。</td>
</tr>
<tr>
<td>
clear()</td>
<td>
清空容器,即删除容器中存储的所有元素。</td>
</tr>
<tr>
<td>
swap()</td>
<td>
交换 2 个 unordered_set&nbsp;容器存储的元素,前提是必须保证这 2 个容器的类型完全相等。</td>
</tr>
<tr>
<td>
bucket_count()</td>
<td>
返回当前容器底层存储元素时,使用桶(一个线性链表代表一个桶)的数量。</td>
</tr>
<tr>
<td>
max_bucket_count()</td>
<td>
返回当前系统中unordered_set&nbsp;容器底层最多可以使用多少桶。</td>
</tr>
<tr>
<td>
bucket_size(n)</td>
<td>
返回第 n 个桶中存储元素的数量。</td>
</tr>
<tr>
<td>
bucket(key)</td>
<td>
返回值为 key 的元素所在桶的编号。</td>
</tr>
<tr>
<td>
load_factor()</td>
<td>
返回 unordered_set&nbsp;容器中当前的负载因子。负载因子指的是的当前容器中存储元素的数量size()和使用桶数bucket_count())的比值,即 load_factor() = size() / bucket_count()。</td>
</tr>
<tr>
<td>
max_load_factor()</td>
<td>
返回或者设置当前 unordered_set&nbsp;容器的负载因子。</td>
</tr>
<tr>
<td>
rehash(n)</td>
<td>
将当前容器底层使用桶的数量设置为 n。</td>
</tr>
<tr>
<td>
reserve()</td>
<td>
将存储桶的数量(也就是 bucket_count() 方法的返回值)设置为至少容纳 count 个元(不超过最大负载因子)所需的数量,并重新整理容器。</td>
</tr>
<tr>
<td>
hash_function()</td>
<td>
返回当前容器使用的哈希函数对象。</td>
</tr>
</tbody>
</table>
<br />
注意,此容器模板类中没有重载 [ ] 运算符,也没有提供 at() 成员方法。不仅如此,由于 unordered_set 容器内部存储的元素值不能被修改,因此无论使用那个迭代器方法获得的迭代器,都不能用于修改容器中元素的值。<br />
<br />
另外,对于实现互换 2 个相同类型 unordered_set 容器的所有元素,除了调用表 2 中的 swap() 成员方法外,还可以使用 STL 标准库提供的 swap() 非成员函数,它们具有相同的名称,用法也相同(都只需要传入 2 个参数即可),仅是调用方式上有差别。<br />
<br />
下面的样例演示了表 2 中部分成员方法的用法:<br />
<pre class="cpp">
#include &lt;iostream&gt;
#include &lt;string&gt;
#include &lt;unordered_set&gt;
using namespace std;
int main()
{
//创建一个空的unordered_set容器
std::unordered_set&lt;std::string&gt; uset;
//给 uset 容器添加数据
uset.emplace(&quot;http://c.biancheng.net/java/&quot;);
uset.emplace(&quot;http://c.biancheng.net/c/&quot;);
uset.emplace(&quot;http://c.biancheng.net/python/&quot;);
//查看当前 uset 容器存储元素的个数
cout &lt;&lt; &quot;uset size = &quot; &lt;&lt; uset.size() &lt;&lt; endl;
//遍历输出 uset 容器存储的所有元素
<a href='/view/1811.html' target='_blank'>for</a> (auto iter = uset.begin(); iter != uset.end(); ++iter) {
cout &lt;&lt; *iter &lt;&lt; endl;
}
return 0;
}</pre>
程序执行结果为:
<p class="info-box">
uset size = 3<br />
http://c.biancheng.net/java/<br />
http://c.biancheng.net/c/<br />
http://c.biancheng.net/python/</p>
<blockquote>
<p>
注意,表 2 中绝大多数成员方法的用法,都和 unordered_map 容器提供的同名成员方法相同,读者可翻阅前面的文章做详细了解,当然也可以到<a href="http://www.cplusplus.com/reference/unordered_set/unordered_set/" target="_blank"> C++<br />
STL标准库官网</a>查询。</p>
</blockquote>
</div>