unordered_set
1.unordered_set和set的使用方法很像,除了unordered_set的元素时无序的。
2.模板参数是:
template<class Value,
class HashFcn = hash<Value>,
class EqualKey = equal_to<Value>,
class Alloc = alloc>
能看到HashFcn的默认类型就是标准库内置hash模板类的一个偏特化的版本。而如果标准库的hash没有针对Value的偏特化版本,用户自己就必须提供一个自定义的重载了()
符号的仿函数类。
默认的比较函数equal_to<Value>
也可能不符合使用要求,因为它本质上就是调用Value重载的==
符号。假如输入的是一个c风格的字符串,Value是const char*
,直接用==
号比较,效果是指针进行比较,不是我们想要的。所以需要自定义一个类,在类里面用strcmp
实现。
3.内部使用hashtable。
hashtable的模板参数是:
template <class Value,
class Key,
class HashFcn,
class ExtractKey,
class EqualKey,
class Alloc>
unordered_set元素的键值就是实值,实值就是键值,所以使用的hashtable的Key和Value模板参数都是unordered_set模板参数中的Value,而ExtractKey就是identity<Value>
。
4.构造函数
默认构造函数,使用大小为100的表格,当然它会被增大成一个质数。
对于只提供表格大小的构造函数,会用模板参数里的类HashFcn默认构造一个对象,用模板参数里的型别EqualKey默认构造一个对象,,来初始化内置的hashtable类型。用户也可以自己提供一个HashFcn类型的对象和EqualKey类型的对象来作为构造函数的参数。
参数为两个迭代器的版本,实际上是调用了底层hashtable的insert_unique
函数。
unordered_map
1.unordered_map和map的使用方法很像,除了unordered_map的元素是无序的。
2.模板参数是:
template<class Value,
class T,
class HashFcn = hash<Value>,
class EqualKey = equal_to<Value>,
class Alloc = alloc>
HashFcn
类型和EqualKey
类型都和unordered_set一样,有时候可能需要用户提供。
3.内部还是使用hashtable。
hashtable的模板参数是:
template <class Value,
class Key,
class HashFcn,
class ExtractKey,
class EqualKey,
class Alloc>
这里的Value
是键值对,所以hashtable的Value
类型应该是pair<const Key, T>
。注意这里的键的类型是const类型,这和map中一样,不允许修改键。
ExtractKey
类型使用select1st<pair<const Key, T>>
,实际上就是选出pair类型的first成员。
参数为两个迭代器的版本,实际上是调用了底层hashtable的insert_unique
函数。
4.和map一样,也重载了[]
符号:
T& operator[](const key_type& key) {
return rep.find_or_insert(value_type(key, T())).second;
}
hashtable的find_or_insert
函数返回的是Value类型,而在3中我们知道,在unordered_map中,这个Value被定义成pair<const Key, T>
,因此,取出它的second成员返回。
unordered_multiset
1.unordered_multiset和unordered_set的唯一区别在于,它的插入操作使用的是insert_equal
,而后者使用的是insert_unique
。
unordered_multimap
1.unordered_multimap和unordered_map的区别在于,它的插入操作使用insert_equal
,而后者使用的是insert_unique
。并且它没有重载的[]
符号。