boost :: unordered_multimap: получить все элементы в корзине эффективно?

Я могу получить все элементы в одном ведре с этим кодом:

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 к первому элементу в сегменте и перебирать его до конца сегмента, поэтому, если в хэш-таблице есть только одно значение для данного индекса (где индекс — это Hash(key)) Я буду повторять только один элемент и получаю bucket 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) ? Это то, что я думаю, потому что объяснение bucket() Функция от сайта повышения:

Возвращает: Индекс корзины, которая будет содержать элемент с
ключ к.

                                 ^^^

Я думаю, что это означает, что я должен сначала find(key) в мультикарте, чтобы узнать, присутствует ли ключ, потому что вызов bucket(key) вернет индекс, который не является хешем, но по модулю хеша (bucket_from_hash) в хеш-таблице, под которой хранится ключ, если он присутствует. Так что по модулю, который делается с bucket_countЕсли ключ не был вставлен, я переберу виртуальное ведро, в котором оно будет находиться в текущих условиях, и что для меня наиболее важно: могут быть и другие хэши, так как bucket_count может быть меньше моего хэша (я использую 16- немного MyHash<key> 32-битного ключа в качестве хэш-функции, предоставляемой в многопользовательском конструкторе). Это правильно?

0

Решение

Я бы начал работать с диапазонами, вот так:

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 вместо.

3

Другие решения

Других решений пока нет …