1

次のように定義されたハッシュマップがあります

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

私の質問は、必要に応じてキーを変更する正しい方法でしょうか? 悪い副作用はありますか?

4

2 に答える 2

3

コンテナから要素を削除し、新しいキーで再度追加する必要があります。

どの C++ 連想コンテナーも、重要な方法でキーを変更することをサポートしていません (重要な変更は、ハッシュされたコンテナーのハッシュの結果または順序付けられたコンテナーの比較の結果を変更することを意味します)。

(なんらかの方法で const の正確性システムを回避することによって) キーを変更した場合、ルックアップから予測できない結果が得られます。

于 2010-02-17T15:25:05.983 に答える
2

constのメンバーであるためキーを変更できないだけでなく、イテレータを無効にせずにpairメンバーを消去または挿入することはできません。が無効化されると、コンテナーから次のアイテムを取得するためにインクリメントすることはできません。hash_mapii

より良いアルゴリズムがあるかもしれません (おそらく存在します) が、キーを変更したい要素の要素 (またはキーのみ) のコピーを他の一時的なコンテナーに保存する必要があると思います。あなたのforループで。次に、一時コンテナーをウォークし、その中の情報を使用して次のことを行います。

  • hash_map元のコンテナでキーを変更する要素を取得します
  • erase()元のコンテナのその要素
  • insert()新しいキーと元の値を持つ新しい要素をhash_map

その後、一時コンテナーをダンプできます。

于 2010-02-17T16:17:48.610 に答える