0

std::mapさまざまなタイプのオブジェクトをラップするために使用するクラスへのポインターを格納するために使用しています。これは、Lua スクリプト言語や他の Lua タイプのテーブルを表すために使用されています。テーブル ラッパーを作成しているstd::mapときに、ポインタをツリーに格納するときにデフォルトのコンパレータを使用することに気付きました。最初はこれが問題のように思えましたが、もう少し考えて、そうではないと判断しました。デフォルトの比較が何であれ、それは本当に重要ではありません (私は思います)。

だから、私が求めているのはこれです。それは本当に問題ではないというのは本当ですか?もしそうなら、いつカスタムコンパレータを使用したいですか?

4

2 に答える 2

2

あなたの質問には少し明確さが欠けていると思います。あなたが意味すると仮定しましょう:

  1. std::mapのキーは、クラスへのポインターです。は特定されていないものです。
  2. 順序付けされた連想コンテナーを使用していますが、正確な検索のみを行うため、キーが格納されている順序はあまり気にしません。

その場合、ポインターをアドレスで比較することは問題ありません。ただし、このユースケースではunordered_map、C++11 で正式に利用可能ですが、C++03 でも c++ ライブラリで利用できることが多い (別名ハッシュ テーブル) を使用することをお勧めします。

于 2012-11-01T04:30:49.350 に答える
2

map は、キーの弱い等価性に基づいて値を格納および取得します。マップ m1 でキー k1 を探す場合、(マップはバランスの取れた b ツリーとして実装されているため) 検索はルート ノードから開始され、ノードの値が k1 より小さいか大きいかに基づいて左または右に進みます。 k1. また、「value_at_node < k1」と「k1 < value_at_node」の両方の比較が false の場合、マップはキーが現在のノードで見つかったと結論付けます。

キーがポインター型の場合、ポインター値はデフォルトのコンパレーターによって比較されます。また、ポインター値の弱同値は、強同値 ( = 演算子) と同じ結果になります。キーの場所 (メモリ内のアドレス) で行われるキー比較が目的ではなく、代わりにアドレスの値に基づいて比較する場合は、カスタム コンパレータを使用する必要があります。さらに言えば、マップ コンテナに < 演算子が定義されていないキー タイプは使用できません。コンパイラ エラーが発生します。

コンパレーターは弱い等価規則によく一致する必要があります - !(v < k) && !(k < v) は v == k と同じです。これは、カスタマイズされたコンパレーターによって正しく実装され、支持されるべきです。

于 2012-11-01T04:50:46.677 に答える