繁体   English   中英

hash_map:为什么它定义less而不是equal_to

[英]hash_map: why it defines less, rather than equal_to

C ++,使用Visual Studio 2010.关于为什么用户定义的hash_map特征实际上需要总排序的问题。

我有一个简单的结构,比如FOO ,它只有一些整数。 我想使用hash_map来存储FOO的结构, hash_map是一个键是无序的哈希表。 我只需要快速搜索其相关值,所以这是一个正确的选择: hash_map<FOO, int32_t>

但是,我需要为FOO实现自己的哈希函数和一些比较函数。 以下是从MSDN获取的hash_map的定义:

template <
   class Key, 
   class Type, 
   class Traits=hash_compare<Key, less<Key> >, 
   class Allocator=allocator<pair <const Key, Type> > 
>
class hash_map

原来我需要实现hash_compare函数:

template<class Key, class Traits = less<Key> >
   class hash_compare
   {
   Traits comp;
public:
   const size_t bucket_size = 4;
   const size_t min_buckets = 8;
   hash_compare( );
   hash_compare( Traits pred );
   size_t operator( )( const Key& _Key ) const; // This is a hash function
   bool operator( )(                            // This is an ordering function
      const Key& _Key1,
      const Key& _Key2
   ) const;
   };

以下是来自MSDN的bool operatod()的详细说明:

对于序列中_Key2 之前的 Key类型的任何值_Key1,并且具有相同的散列值(散列函数返回的值),hash_comp(_Key2,_Key1)为false。 该函数必须对Key类型的值施加总排序

hash_compare提供的函数返回comp(_Key2,_Key1),其中comp是Traits类型的存储对象,您可以在构造对象hash_comp时指定它。 对于默认的Traits参数类型less,排序键的值不会减少。

FOO编写hash_compare类很容易。 这个问题不是要问如何实现一个类。 但是,对于我来说,为什么他们将默认特征参数设置为less<key>并且需要总排序并不是直截了当的。

hash_map是一种无序数据结构。 所以,我认为使用equal_tonot_equal_to而不是lessgreater是足够的。 但是,MSDN的描述明确指出密钥是有序的,这让我感到困惑。

我是否误解了hash_map的定义? 为什么STL的hash_map实际上需要其密钥的订单?

您正在查看的hash_map是VS2003中stdext的Microsoft扩展,实际上现在是Visual C ++中的stdext - 它不是STL的一部分。

std::unordered_map是一个关联容器的官方 STL版本,具有可访问密钥的值访问权限 - 正如您所期望的那样,谓词是相等的。

template<class Key,
    class Ty,
    class Hash = std::hash<Key>,
    class Pred = std::equal_to<Key>,
    class Alloc = std::allocator<std::pair<const Key, Ty> > >
    class unordered_map;

对于序列中_Key2 之前的 Key类型的任何值_Key1,并且具有相同的散列值(散列函数返回的值),hash_comp(_Key2,_Key1)为false。 该函数必须对Key类型的值施加总排序

具有相同散列值的密钥的总排序保证了散列到同一桶的密钥的总排序。

这提供了更有效地实现在特定桶内搜索密钥的机会 - 例如,Θ(log n)二分搜索是可能的。 如果没有这样的保证排序,最坏的情况(许多不同的密钥都在同一个桶中,因为它们都散列到相同的值)是Θ(n)。

hash_map的确切要求因实现而异,其中一些(如您所见)并没有多大意义。 这就是为什么他们决定不在 TR1和/或C ++ 0x中包含hash_map (或hash_* )的部分原因。 相反,它们有unordered_[multi](map|set) ,它只需要equal_key ,而不是operator<

结论:除非你有一个非常出色的理由,否则使用unordered_map而不是hash_map

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM