我有一个哈希图定义为

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();
}

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

有帮助吗?

解决方案

您不得不从容器中取出的元素,并与新的密钥重新添加。

的C ++关联容器的无支持改变一个显著方式(其中显著意味着变化改变了散列的诸结果中的哈希容器或以有序容器的comparrsion)。在键

如果你没有修改密钥(以某种方式规避const正确性系统),你会从查询得到不可预知的结果。

其他提示

您不仅不能更改密钥,因为它是 const 的成员 pair, ,您无法删除或插入成员 hash_map 不使迭代器无效, i, , 你有。什么时候 i 已失效,您无法增加它以从容器中获取下一个项目。

可能有(而且可能是)更好的算法,但我认为您需要做的是将您想要更改键的元素的元素(或只是键)的副本存储在其他临时容器中在你的 for 环形。然后遍历临时容器并使用其中的信息来:

  • 获取原始元素中要更改其键的元素 hash_map 容器
  • erase() 原始容器中的该元素
  • insert() 一个带有新键和原始值的新元素返回到 hash_map

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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top