2017-02-25 48 views
4

我想用我的class作爲keymap,所以我超載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<)不會修改其操作的對象。如果是這樣的,即

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

那樣操作者能夠與STL容器如std::map可以使用需要指定,該方法是通過將關鍵字const在聲明的端恆定的情況下,。


您當前的會員運營商的版本,翻譯成一個獨立的運營商將作爲看:

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

通告lhs缺乏const。它本身仍然是正確的,但非典型。你需要提供一個l值爲lhs。如果你提供了其他的東西,你會得到``找不到操作員...''錯誤。 STL std::map並不期望這兩者,因此你的錯誤,可能來自標準頭文件,在模板實現的深處。

+1

因此編譯時錯誤不是來自他聲明重載運算符的方式,它來自成員重載運算符用於命令映射,如果它的兩個參數都是const,它將只接受重載的<<運算符。 – user

+0

是的,就是這樣。 –

+0

這是正確的 - 操作符不需要是「const」。有些通常不是(例如'operator ='),有些通常是。但是請注意,非常量運算符需要一個「左值」作爲左邊的參數,如果不提供一個,你會得到一個類似的錯誤。 – CygnusX1

2

假設ab都是Syl型的,第一個(構件形式)是無效的在表達a < b如果aconst,並會導致編譯錯誤。

爲了解決這個問題,需要指定該構件operator<()作爲

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

沒有這種後const,在表達式a < ba不能const(即operator<()允許改變它)。

您的第二種形式是正確的,因爲它指定兩個操作數都是const引用。

<這樣的比較運算符通常不會改變它們的操作數。 const限定符傳達了這個事實。

請記住,您可以提供會員表格或非會員表格。提供兩者都會因模糊而導致錯誤(編譯器沒有理由相對於另一個偏好,當它看到像a < b這樣的表達式時)。

+0

謝謝,這工作! – Tris