2009-05-20 6 views
2

これは可能ですか?STLマップでstd :: pairの代わりにカスタムクラスを使用できますか?

#include <map> 

class Example { 

    private: 
    std::map<std::string, std::string, less<std::string>, 
    std::allocator< CustomPair<std::string, std::string> > > myMap; 
}; 

上記の例では、CustomPairはキーと値を保持するテンプレートクラスです。これが可能であれば、それは簡単なのか、それとも私が見なければならないものがありますか?

答えて

7

あなたの本当の意図がここにあると推測することができます。だから、すでにキーと値の両方を含むクラスがあると仮定します。その場合は、std :: setをカスタム比較で使用する方がstd :: mapよりも良い選択となる場合があります。

次に、クラスのキー部分だけを比較する比較を提供する必要があります。キー部分は、オブジェクトがセット内にある限り、const(時間の経過とともに変化しない)でなければなりません。 コメントの中で述べたように、セットの要素はconstとしてしかアクセスできません。したがって、そのような要素の値を変更するには、書き込みアクセスをconst_castするか、メンバーを変更可能に宣言する必要があります。

iainもう1つの非常に良い提案がありました。まれにコンテナに挿入してほとんどコンテナにアクセスして要素を検索すると、ソートされたstd :: vectorとstd :: binary_searchはセットの非常に有効な代替手段です。

+1

この問題の主な問題は、順序が維持されるためにsetが一定の値を保持するため、CustomPairは2番目のメンバを変更可能にし、最初のメンバのみを使用するよう比較を強制する必要があります。 –

+0

@Greg Rogersありがとう、答えに鍵の部分のconstnessを加えました。 – lothar

+0

私はOPの意図が分かりませんでしたが、彼の質問は、<...>の代わりに、カスタムパラメータ<...>をテンプレートパラメータとしてstd :: allocatorに渡すことでした。これは質問に答えません。 – Ari

3

std :: setを使用する可能性が高くなります。

-2

std::allocatorの使用がrebind<std::pair>で行われ、CustomPairの選択を無効にするので、あなたはそれを行うことはできますが、望ましい効果を得ることはできないと思います。実際には、あなたがそこに置くタイプは関係なく、STL関数はそれを無視します。それらのうちのいくつかは間違いなくこれを行うだろうが、私はすべてが確実ではないと思う。厳密に言えば、これはほぼ確実に実装に依存します。私は標準が何を言っているのか分からない。

+1

@Ariアロケータは、STLコンテナの内部実装を変更することはできません。コンテナの内部データのメモリがどこにどのように割り当てられているかだけ変更できます。 – lothar

+0

確かに、私の答えは、OPが文字通り尋ねたことをすることができると言いますが、あなたは望みの効果を得られません。私はこれがどのように可能であるかを説明するために続けました(コンパイルは大丈夫ですが、あなたの考えをしません)。どうしたの。 – Ari

3

"効果的なSTL"の章23「並べ替えられたベクトルと連想型のコンテナの交換を検討する」で説明したように、lotharで説明したようなセットを使用するか、ソート済みのstd::vectorを使用します。

これは、カスタムコンパイラを使用してソートされたベクトルのstd::binary_searchが地図のルックアップよりも速く、時には高速であり、繰り返しがはるかに高速であることを合理的に示しています。挿入操作はより高価です(挿入するたびにソートを呼び出す必要があります)。多くのマップユースケースは非常にまれにしか挿入されません。

ベクターは、セットよりも柔軟性があります。

私は2000年の複雑なオブジェクト(intで索引付けされている)のマップをこのアプローチに置き換えました。マップ内のすべてのオブジェクトがサーバークラスシステムで50秒から5未満になりました。地図検索の時間に顕著な違いはありませんでした。

+0

std :: vectorのバイナリ検索のための+1 – lothar

+1

std :: binary_search()は、指定された値が存在するかどうかを返します。あなたはstd :: equal_range()を意味しましたか? – bk1e

+0

ありがとうございます、はいあなたは正しいですequal_range – iain

関連する問題