警告:これは、非常にです。希望の動作の粗いモックアップです。これは良いコードの近くにはありませんが、すばやく、これを行う手法を実証する必要があります。
独自のロールを検討する前に、Boostのmulti_index
などの既存のソリューションを使用する必要があります。それは、より簡単で、速く、エラーを起こしにくく、より良い設計になります。
template<typename Key, typename Val>
class OrderedMap
{
private:
std::vector<std::pair<Key, Val>> ordered;
std::map<Key, std::size_t> lookup;
public:
void insert(Key k, Val v)
{
ordered.push_back(std::pair<Key, Val>(k, v));
lookup.emplace(k, ordered.size() - 1);
}
Val find(Key k)
{
std::size_t index = lookup[k];
return ordered[index].second;
}
// "typename" needed as the "iterator" is a dependent type
typename std::vector<std::pair<Key, Val>>::iterator begin()
{
return ordered.begin();
}
typename std::vector<std::pair<Key, Val>>::iterator end()
{
return ordered.end();
}
};
我々が必要なのは、キーと値のインデックスとの間の関連を追跡するために挿入された要素の実際の順序を追跡し、そしてstd::map<Key, std::size_t>
するstd::vector<std::pair<Key, Val>>
です。次に、このクラスから必要な機能をこれらの内部バッキング/ルックアップ構造の機能に委譲することができます。
このクラスが望む動作と内部のコンテナの間で提供するインターフェイスは、好きなだけ堅牢にすることができます。ここでは、デモに必要な醜い骨を取り除きました。
See a quick demo here。
OrderedMap<std::string, int> m;
m.insert("1", 1);
m.insert("2", 2);
m.insert("3", 3);
std::cout << m.find("2") << std::endl << std::endl;
for (auto i = m.begin(); i != m.end(); i++)
std::cout << i->first << " " << i->second << std::endl;
std::cout << std::endl;
は出力が得られます。もちろん
2
1 1
2 2
3 3
それは言語で可能です - あなたはバッキングを使用してキーのルックアップ削除/挿入されたアイテムと 'ベクトル'は '地図を'使用して試してみました挿入順に? –
hnefatl
@KillzoneKidそれは驚くことではありません!それが、私がこれに関して持っていた最初の偽りの解決策でした。 – JosephJerrel
あなたはboost :: multi_indexを見ましたか?私はそれがあなたが後になっていることをすることができるかどうかは分かりません。 – SoronelHaetir