1

キーがクラスであるマップに挿入しようとしています。以下のように、クラスで operator< 関数をオーバーロードしました。

struct MyType
{
    int a, b, c;
    bool operator<(const MyType& Rhs) const
    {
       return (a<Rhs.a) || (b<Rhs.b) || (c<Rhs.c);
    }
}

ただし、特定の (一意の) キーについては、値がマップで上書きされています。

複数値キーに推奨される operator< メソッドは何ですか?

タプルを使用する構造体の定義演算子 < を見たことがありますが、できれば長い手で書きたいと思います。

4

4 に答える 4

5

代わりにこれを行います:

return std::tie(a, b, c) < std::tie(Rhs.a, Rhs.b, Rhs.c);

する必要があり#include <tuple>ます。

于 2012-12-14T14:17:19.497 に答える
3

この表現

(a<Rhs.a) || (b<Rhs.b) || (c<Rhs.c)

厳密な弱い順序付けを作成しません: と仮定a > Rhs.aしますが、b < Rhs.b. あなたの式は を返しますがtrue、そうあるべきですfalse: s が同じb場合にのみ同点を解決するために使用し、 s とs が同じ場合にのみ s を使用する必要があります。acab

これは、次の「階段」表現につながります。

(a<Rhs.a) ||
(a==Rhs.a && b<Rhs.b) ||
(a==Rhs.a && b==Rhs.b && c<Rhs.c)

これは、Kerrek SB の回答で提案されている式を記述する長い方法です。はるかに優れた可読性のために使用することをお勧めします。

于 2012-12-14T14:27:13.650 に答える
1

問題は、たとえば 2 つのインスタンスをインスタンスMyTypeM1 = {1, 1, 2}するM2 = {1, 2, 1}と、不幸な状況が発生しM1 < M2 M2 < M1 !

これを修正するにはa bcいくつかの重要性/順序を割り当てる必要があります。

struct MyType
{
    int a, b, c;
    bool operator<(const MyType& Rhs) const
    {
       if (a < Rhs.a) return true;
       if (a > Rhs.a) return false;
       if (b < Rhs.b) return true;
       if (b > Rhs.b) return false;
       return c < Rhs.c;
    }
}

(これは、dasblinkenlight の回答で式を記述する最適な方法ではありませんが、理解しやすいかもしれません)。

しかし、なぜこれが必要なのかを理解したら、 に切り替える必要がありますtuple。これは実際にはボイラープレート コードです。

于 2012-12-14T14:28:28.373 に答える
0

そのタイプのキーを持つマップが必要でコンパレーターが不要な場合は、boost::unordered_map を使用し、boost::hash_combine を使用してタイプのハッシュを定義することをお勧めします。

于 2012-12-14T15:08:59.680 に答える