2017-02-25 8 views
4

classkeyとしてmapに入力したいので、私はoperator+をオーバーロードします。友人の機能としてそれをオーバーロードするとうまくいきます。私はそれをクラス内のメンバ関数としてオーバーロードすると、コンパイルエラーが発生します。演算子をメンバー関数としてオーバーロードすることはできません

error C2678: binary '<': no operator found which takes a left-hand operand of type 'const Syl' (or there is no acceptable conversion)'.

詳細には、これはコンパイルし、コンパイルエラーを生成しません:

Syl.h

bool operator< (const Syl& rhs); 

Syl.cpp

bool Syl::operator< (const Syl& rhs) { return false; } 

を、これはコンパイルしている間。

Syl.h

friend bool operator< (const Syl& lhs, const Syl& rhs); 

Syl.cpp

bool operator< (const Syl& lhs, const Syl& rhs) { return false; } 

私は理由を知りません。私は演算子<がバイナリであることを知っていますが、とにかくそれを関数のメンバーとして過負荷にしていますか?

+1

オーバーロードの解決方法と暗黙的な変換が機能するため、とにかく「友人」バージョンが良いアイデアです。 –

+0

友好的なバージョンでは、両方のオペランドが 'const'として指定され、他のバージョンでは入力パラメータが' const'としか指定されません。メソッドをそのようにマークする必要があります...エラーを注意深く読み、 'const'、' signed'などの単語の意味に細心の注意を払う必要があります。 – Kupto

答えて

3

通常、operator<などのメンバー演算子は、操作対象のオブジェクトを変更しません。それはあなたが方法は、宣言の末尾にキーワードconstを入れることで一定であることを指定する必要がある場合、すなわち

class Syl { 
    ... 
    public: 
    bool operator<(const Syl& rhs) const; 
} 

ある場合は、そのようなオペレータは、このようなstd::mapとしてSTLコンテナで使用することができます。


メンバ演算子のあなたの現在のバージョン、スタンドアロンオペレータに翻訳されたときのようになります。

friend bool operator<(Syl& lhs, const Syl& rhs); 

お知らせlhsためconstの欠如。まだそれ自体は正しいが、非典型的である。 l値はlhsとする必要があります。あなたが何か他のものを提供すれば、`` no operator found ... ''エラーが発生します。 STL std::mapは、テンプレート実装のどこかで、おそらく標準ヘッダーからのエラーであると考えていません。 aconstで、コンパイルエラーになります場合

+1

コンパイル時のエラーは、それは、引数が両方ともconstの場合、オーバーロードされた '<'演算子のみを受け付けるマップを注文するためにメンバーのオーバーロードされた演算子が使用されるという事実から来ています。 – user

+0

はい、まさにそれです。 –

+0

これは正しい - 演算子は 'const'である必要はありません。いくつかは通常はありません(たとえば、 'operator =')。通常はいくつかあります。ただし、非const演算子は左引数として 'lvalue'を必要とします。もしあなたがそれを提供しなければ、同様のエラーが発生します。 – CygnusX1

2

あなたの最初の(会員フォーム)、abはタイプSylの両方あると仮定すると、式a < bでは有効ではありません。

はそれを修正するには、あなたが表現a < bで、その末尾constなければ

bool operator< (const Syl& rhs) const; // note the trailing const 

として部材operator<()を指定する必要があり、aconstすることはできません(すなわちoperator<()はそれを変更することが許可されます)。

両方のオペランドがconstの参照であることを指定しているため、2番目の形式は正しいです。

<のような比較演算子は、通常、そのオペランドのいずれかを変更しません。 const修飾子はその旨を伝えます。

メンバーフォームまたはメンバー以外のフォームを指定できることにご注意ください。両方を指定すると、あいまいさのためにエラーが発生します(コンパイラは、a < bのような式を見たときに、コンパイラを優先して優先させることはできません)。

+0

ありがとう、それは動作します! – Tris

関連する問題