我可以使用以下代码将所有元素放在一个存储桶中:
typedef boost::unordered_multimap< key, myClass*, MyHash<key> >
HashMMap;
HashMMap::iterator it;
it = hashMMap_.find( someKey);
int bucketIndex = hashMMap_.bucket( someKey);
int bucketSize = hashMMap_.bucket_size( bucketIndex);
qDebug() << "index of bucket with key:" << someKey << " is:"
<< bucketIndex;
qDebug() << "number of elements in bucket with index:" << bucketIndex << " is:"
<< bucketSize;
HashMMap::local_iterator lit;
/* begin of bucket with index bucketIndex */
lit = hashMMap_.begin( bucketIndex);
for ( ; lit != sender_.hashMMap_.end( bucketIndex); ++lit) {
qDebug() << "(*lit).first:" << (*lit).first << ", (*lit).second:" <<
(*lit).second << ", (*lit).second->something_:" <<
(*lit).second->something_;
}
我想将一个local_iterator放到一个桶中的第一个元素并迭代它直到桶结束,所以如果哈希表中给定索引只有一个值(其中index是Hash(key)
)我将迭代单个元素并接收桶end(),并且在许多元素的情况下,我将迭代整个桶(所有值具有相等的散列)。如果没有bucketIndex
,hashMMap_.begin( bucketIndex)
和hashMMap_.end( bucketIndex)
?
所以基本上我想得到一个像这样的local_iterator:
HashMMap::local_iterator lit = hashMMap_.find_bucket_if_present( someKey);
其他问题是:如果find()
在调用int bucketIndex = hashMMap_.bucket( someKey)
之前返回元素的迭代器,我是否必须先测试?这是我的想法,因为来自boost网站的bucket()
函数的解释是:
返回:包含元素的存储桶的索引 关键k。
^^^
我认为这意味着我首先要在多图中find(key)
知道密钥是否存在,因为对bucket(key)
的调用将返回一个索引,该索引不是散列而是散列模数({ {1}})在存在密钥的哈希表中,如果存在密钥。因此,由于使用bucket_from_hash
完成的模数,如果未插入密钥,我将迭代虚拟存储桶,在当前情况下,它将对我来说最重要的是:也可能存在不同的哈希值因为bucket_count可能小于我的哈希值(我使用32位密钥的16位bucket_count
作为多地图构造函数中提供的哈希函数)。这是对的吗?
答案 0 :(得分:3)
我会开始使用范围,如下:
template<typename BoostUnorderedMap, typename Key>
boost::iterator_range< typename BoostUnorderedMap::local_iterator > get_bucket_range( BoostUnorderedMap& myMap, Key const& k ) {
int bucketIndex = myMap.bucket( k );
return boost::iterator_range< typename BoostUnorderedMap::local_iterator >(
myMap.begin(bucketIndex),
myMap.end(bucketIndex)
}
}
template<typename BoostUnorderedMap, typename Key>
boost::iterator_range< typename BoostUnorderedMap::local_const_iterator > get_bucket_range( BoostUnorderedMap const& myMap, Key const& k ) {
int bucketIndex = myMap.bucket( k );
return boost::iterator_range< typename BoostUnorderedMap::local_const_iterator >(
myMap.begin(bucketIndex),
myMap.end(bucketIndex)
}
}
然后,至少在C ++ 11中,您可以执行以下操作:
for (auto && entry : get_bucket_range( some_map, "bob" ) )
它会遍历"bob"
存储桶中的所有内容。
虽然这确实使用了bucketIndex
,但它会隐藏最终消费者的这些详细信息,而只是为您提供boost::range
。