2010-02-17 4 views
1

У меня есть хэш-карта определяется какСТЛ hash_map - модифицирования ключ

class KeyType { 
    int key; 
    mutable bool flag; 
    KeyType(int key) : key(key), flag(false) {} 
    void setFlag() const { flag = true; } 
}; 

struct KeyType_hasher { 
    size_t operator()(const KeyType& s) const { 
     return static_cast<size_t> key; 
    } 
}; 

struct KeyType_equal { 
    size_t operator()(const KeyType& s1, const KeyType& s2) const { 
     return s1.key == s2.key; 
    } 
}; 

typedef hash_map<KeyType , ValueType, KeyType_hasher, KeyType_equal > KeyValueMap; 

Позже в коде у меня есть место, где я должен цикл, хотя на карте и применить функцию к каждому значению я нахожу. Основываясь на результатах функции, я также должен изменить ключ на итераторе.

KeyValueMap theMap; 
// theMap[key1] = value1; 
// theMap[key2] = value2; 
// theMap[key3] = value3; 
for(KeyValueMap::iterator i = theMap.begin(); i != theMap.end(); ++i) { 
    if(true == ValueFunction(i->second)) 
     i->first.setFlag(); 
} 

Вопрос в том, будет ли это правильным способом изменения ключа, если нужно? Имеет ли он какие-либо плохие побочные эффекты?

+0

Почему вы хотите изменить ... ключ? Почему бы не сохранить флаг в части ценности!? –

+0

@Matthieu M Может быть; но реализация, которую я должен был использовать, была немного причудливой для изменений в объекте ValueType. –

+0

Ах да, мы не всегда можем выбрать:/ –

ответ

3

Вам нужно будет удалить элемент из контейнера и повторно добавить его с помощью нового ключа.

Ни один из ассоциативных контейнеров C++ не поддерживает изменение ключа существенным образом (где значительный означает изменение изменяет результаты хэша в хэшированном контейнере или comparrsion в упорядоченном контейнере).

Если вы модифицировали ключ (каким-то образом обходив систему соответствия const), вы получите непредсказуемые результаты поиска.

+0

Спасибо, Джо. Я отредактировал мой оригинальный вопрос; добавили определения для KeyType_hasher и KeyType_equal. Они ничего не полагаются на флаг. –

+1

Тогда все должно быть хорошо. –

+2

Будьте осторожны - вы не можете «стереть()» или «insert()» в 'hash_map' в этом цикле' for', поскольку это приведет к недействительности итератора в нем. –

2

Вы можете не только не изменить ключ, так как это const член pair, вы не можете удалить или вставить член в hash_map без недействительности итератора, i, у вас есть. Когда i недействителен, вы не можете увеличить его, чтобы получить следующий элемент из контейнера.

Может быть (и, вероятно, есть) лучший алгоритм, но я думаю, что вам нужно будет хранить копии элементов (или просто ключей) элементов, которые вы хотите изменить, некоторый другой временный контейнер в вашем цикле for. Затем идти temportary контейнер и использовать информацию в нем:

  • получить элемент, который вы хотите изменить ключ в первоначальном hash_map контейнере
  • erase(), что элемент из оригинального контейнера
  • insert() новый элемент с новым ключом и исходным значением обратно в hash_map

Затем вы можете сбросить временный контейнер.

Смежные вопросы