Удалить диапазон элементов из QHash

Я использую QHash в качестве контейнера, и у меня есть задача удалить все элементы, которые удовлетворяют предикату. Сначала я подумал использовать идиому Erase-remove, оказалось, что QHash не имеет опции для удаления диапазона, а имеет только функцию для удаления одного элемента через итератор.

Функция std::unordered_map (концептуально близкая к QHash в Qt) имеет функцию удаления диапазона.

Это подразумевает вопрос: почему QHash не имеет аналогичной функции и как наилучшим образом удалить элементы из QHash, удовлетворяющие предикату?

2 ответа

Решение

На основании комментариев выясняется, что идиома удаления-удаления не относится к контейнеру QHash.

Поэтому дано описание QHash:: erase, в частности, что оно не нарушает порядок элементов в хэше

В отличие от remove() и take(), эта функция никогда не заставляет QHash перефразировать свою внутреннюю структуру данных. Это означает, что его можно безопасно вызывать во время итерации, и это не повлияет на порядок элементов в хэше.

у нас есть следующий код для удаления элементов, которые удовлетворяют предикату:

for( auto it = hash.begin(); it != hash.end(); ++it )
{
    if( pred(*it) )
    {
        hash.erase(it); 
    }
}

Принятый ответ не работает, поскольку он игнорирует возвращаемое значение из erase(), которое является итератором для следующего элемента в хэше. Вам нужно сделать;

      QHash<QObject *, int> objectHash;
QHash<QObject *, int>::iterator i = objectHash.begin();
while (i != objectHash.end()) {
    if (i.value() == 0) {         // test here
        i = objectHash.erase(i);
    } else {
    ++i;
}

согласно ссылке на документацию Qt - в противном случае вы увеличиваете недопустимый итератор.

Другие вопросы по тегам