Ответ 1
Не могли бы вы каким-то образом испортить max_load_factor, чтобы предотвратить повторное использование?
Да, вы можете установить max_load_factor()
на бесконечность, чтобы не было никакой перезагрузки:
#include <iostream>
#include <limits>
#include <unordered_set>
int main()
{
// initialize
std::unordered_set<int> S;
for (int i = 0; i < 8; ++i)
S.insert(i);
std::cout << "buckets: " << S.bucket_count() << std::endl;
// infinite max load factor => never need to rehash
const auto oldLoadFactor = S.max_load_factor();
S.max_load_factor(std::numeric_limits<float>::infinity());
for (const auto& x : S)
{
if (x > 2)
S.insert(x * 2);
}
// restore load factor, verify same bucket count
S.max_load_factor(oldLoadFactor);
std::cout << "buckets: " << S.bucket_count() << std::endl;
// now force rehash
S.rehash(0);
std::cout << "buckets: " << S.bucket_count() << std::endl;
}
Обратите внимание, что просто установка нового коэффициента загрузки не требует повторной перемотки, поэтому это дешевые операции.
Бит rehash(0)
работает, потому что это запрос: 1) я получаю по крайней мере n ведер, а 2) у меня достаточно ведра, чтобы удовлетворить мой max_load_factor()
. Мы просто используем ноль, чтобы указать, что мы не заботимся о минимальной сумме, мы просто хотим перефразировать, чтобы удовлетворить наш "новый" фактор, как если бы он никогда не менялся до бесконечности.
Конечно, это не исключение; если что-то между звонками на max_load_factor()
, наш старый фактор потерян навсегда. Легко фиксируется с помощью вашей любимой утилиты для защиты области видимости или класса утилиты.
Обратите внимание, что вы не получаете никаких гарантий, если вы будете перебирать новые элементы. Вы будете перебирать существующие элементы, но можете или не будете перебирать новые элементы. Если это нормально (что в нашем чате должно быть), тогда это будет работать.
Например, рассмотрим, как вы перебираете неупорядоченный набор целых чисел и для каждого четного целого x
, вставьте x * 2
. Если они всегда вставлены сразу после вашей текущей позиции (случайно из-за детализации реализации и состояния контейнера), вы никогда не прекратите цикл, за исключением исключений.
Если вам понадобятся некоторые гарантии, вам необходимо использовать альтернативное решение для хранения.