stl hash_map - 修改密钥

时间:2010-02-17 15:20:29

标签: c++ stl iterator hashmap mutable

我有一个定义为

的哈希映射
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();
}

我的问题是,如果必须的话,这是修改密钥的正确方法吗? 它有什么不好的副作用吗?

2 个答案:

答案 0 :(得分:3)

您必须从容器中删除该元素,然后使用新密钥重新添加该元素。

没有一个C ++关联容器支持以显着的方式更改密钥(其中重要意味着更改会改变散列容器中哈希的结果或有序容器中的比较)。 / p>

如果您确实修改了密钥(通过以某种方式绕过const正确性系统),您将从查找中获得不可预测的结果。

答案 1 :(得分:2)

你不仅不能更改密钥,因为它是const的{​​{1}}成员,你不能删除或插入成员到pair而不会使迭代器失效,{{ 1}},你有。当hash_map无效时,您无法递增它以从容器中获取下一个项目。

可能有(并且可能是)更好的算法,但我认为你需要做的是存储你想要更改键的元素的元素(或只是键)的副本i循环中的其他临时容器。然后走出临时容器并使用其中的信息:

  • 获取您要更改原始i容器
  • 中密钥的元素
  • for来自原始容器的元素
  • hash_map新元素,新密钥和原始值返回erase()

然后你可以转储临时容器。