web-dev-qa-db-ja.com

マップのキーとしてのカスタムタイプ-C ++

std :: mapのキーとしてカスタムタイプを割り当てようとしています。これが私がキーとして使っているタイプです。

struct Foo
{
    Foo(std::string s) : foo_value(s){}

    bool operator<(const Foo& foo1) {   return foo_value < foo1.foo_value;  }

    bool operator>(const Foo& foo1) {   return foo_value > foo1.foo_value;  }

    std::string foo_value;
};

std :: mapと一緒に使用すると、次のエラーが発生します。

error C2678: binary '<' : no operator found which takes a left-hand operand of type 'const Foo' (or there is no acceptable conversion) c:\program files\Microsoft visual studio 8\vc\include\functional 143

以下のように構造体を変更すると、すべてうまくいきました。

struct Foo
{
    Foo(std::string s) : foo_value(s)   {}

    friend bool operator<(const Foo& foo,const Foo& foo1) { return foo.foo_value < foo1.foo_value;  }

    friend bool operator>(const Foo& foo,const Foo& foo1) { return foo.foo_value > foo1.foo_value;  }

    std::string foo_value;
};

friendとして演算子をオーバーロードする以外は、何も変更されていません。なぜ最初のコードが機能しないのか疑問に思っていますか?

何かご意見は?

23
Navaneeth K N

私はあなたが必要だと思う

bool operator<(const Foo& foo1) const;

引数の後のconstに注意してください。これは、「your」(比較の左側)オブジェクトを一定にするためです。

オペレーターが1人だけ必要な理由は、必要な順序付けを実装するだけで十分だからです。 「aはbの前に来る必要がありますか?」という抽象的な質問に答えるために。 aがbよりも小さいかどうかを知るだけで十分です。

32
unwind

おそらくconstメンバー演算子を探しています(正しい名前が何であれ)。これは機能します(constに注意):

bool operator<(const Foo& foo1) const { return foo_value < foo1.foo_value;}

編集:削除されたoperator>必要なかったので私の答えから(質問からコピー/貼り付け)、しかしそれはコメントを集めていました:)

注:例をコンパイルしたので、それが必要であると100%確信していますconst

3
stefanB

これについて詳しく教えていただけますか?メンバーをconstにすると(私が知る限り、オブジェクトの状態を変更できないことを意味します-たとえば、プライベート変数を変更する)、「your」が左側になることが保証されるのはなぜですか?

これについてコメントする担当者はまだいません。

constは、「あなたの」が左側になることを魔法のように保証するものではありません。ポスターは、左側(つまり、x in x <y)が比較が呼び出されているオブジェクトであると言っていました。 operator <への引数のconstを使用してyのメンバーを変更から保護するのと同様に、メソッドシグネチャの最後にあるconstを使用してxのメンバーを変更から保護する必要もあります。

0
dpwrussell

引数の後のconstに注意してください。これは、「your」(比較の左側)オブジェクトを一定にするためです。

これについて詳しく教えていただけますか?メンバーをconstにすると(私が知る限り、オブジェクトの状態を変更できないことを意味します-たとえば、プライベート変数を変更する)、「your」が左側になることが保証されるのはなぜですか?

0