6

std::map を作成して初期化した後で、その比較方法を変更することは可能ですか? それとも、それが作成された後だけですか??

定義を変更できないマップを含むクラスの動作を何らかの方法で変更したい。おそらく別のマップを渡すことで、比較動作を変更したいと思います。

4

4 に答える 4

4

可能かもしれませんが、これはテストされていません:

  1. 比較関数の実際の実装へのポインターを内部的に持つ、独自のカスタム コンパレーターを定義します。
  2. this のインスタンスをマップのコンストラクターに渡します (このコンパレーターも使用してマップを入力する必要があります)。
  3. 実際の実装は後で(マップを使用する前に)設定し、後で設定すると内部への影響がわからない...

テスト済みで、上記を実行することは可能ですが、ツリーにアイテムがある場合に比較関数を変更すると、悲惨な結果になる可能性があります...

とにかく - それはあまりにも怪しげに聞こえます....

于 2012-12-18T14:42:58.130 に答える
2

いいえ、それはできません。コンパレーターは、マップのタイプの一部です。intこの質問は、浮動小数点数を格納するために を変更できるかどうかを尋ねるのと同じです。

さらに重要なことに、コンパレータによって提供される順序付けは、マップの内部構造の不可欠な部分です。順序を変更すると、データ構造は一貫した状態ではなくなります。唯一の実行可能なオプションは、新しい順序に関して古いマップの要素から新しいマップを再構築することですが、それは既に可能です:

std::map<T, V, Comp1> m1 = /* ... */;
std::map<T, V, Comp2> m2(m1.begin(), m1.end());

または、タイプの 2 番目のマップをstd::map<std::reference_wrapper<T const>, std::reference_wrapper<V>, Comp2>作成し、元のマップへの参照を入力することもできますが、順序は に従ってComp2ください。その場合、2 つのマップの同期を維持するのはユーザーの責任です。Boost.Multiindex のような高度なコンテナーを使用すると、安全な方法でこれを行うことができます。

于 2012-12-18T15:00:29.033 に答える
1

それは不可能。ただし、別の比較基準と 2 つの反復子コンストラクターを使用して新しいマップを作成し、最初のマップの要素を使用してマップをインスタンス化することができます。

bool  C1(const K&, const K&);
bool  C2(const K&, const K&);

std::map<K, V, C1> orig;
....
std::map<K, V, C2> alternative(orig.begin(), orig.end());
于 2012-12-18T14:43:51.847 に答える
1

テンプレート引数を介してマップにコンパイルされるため、できません。

参照: http://www.cplusplus.com/reference/map/map/ Compareは探しているものです。

あなたは何をしようとしているのですか?

キーとして使用しているクラスを手元に持っているので、コンテキストに反応するために < 演算子または比較関数を実装できます。完全に構築されたオブジェクトを比較関数としてコンストラクターに渡すことができるため、コンテキスト依存の思いやりを実装するためにすべてを渡すことができるはずです。問題は、なぜそうしたいのですか?

実行中に std::map の比較を変更することは、未定義の動作になるため、悪い考えです。std::map の内容が「ソート」されているという事実に基づいています (おそらく RB ツリー)。順序付け関数を変更すると、論理順序が突然変更されます。ただし、マップは魔法のように並べ替えられません。insert または find の次の呼び出しでは、期待どおりの結果が得られない可能性があります。

于 2012-12-18T14:51:54.973 に答える