2009-05-25 65 views
23

我想分配一個自定義類型作爲std :: map的鍵。這是我用作鑰匙的類型。自定義類型作爲鍵的映射 - C++

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 ::地圖,我收到以下錯誤使用。

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; 
}; 

沒有改變。我想知道爲什麼我的第一個代碼不工作?

有什麼想法?

回答

32

我懷疑你需要

bool operator<(const Foo& foo1) const; 

注意const的論點後,這是爲了讓「你」(在比較中左側)對象不變。

只需要一個操作員的原因是它足以實現所需的順序。爲了回答這個抽象問題「是否必須在B之前?」知道a是否小於b就足夠了。

+0

謝謝。那就是訣竅。 – 2009-05-25 11:02:36

+0

你可以進入更多的細節?爲什麼你只需要operator <而不是operator ==或operator>? – bobobobo 2009-12-06 18:38:24

+14

,因爲您可以從操作符<中派生運算符>和運算符==。 '(b b)',所以有operator>。 (!(a skrebbel 2010-08-23 08:39:42

3

它可能正在尋找const成員操作符(不管正確的名稱是什麼)。 這工作(注常量):

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

編輯:從我的答案被刪除operator>,因爲它並不需要(從問題的複製/粘貼),但它吸引了評論:)

注:我100%確定你需要const,因爲我編譯了這個例子。

+2

你不需要> – 2009-05-25 11:04:25

+0

有趣的計算器顯示以前的答案10分鐘前,但是當我提交我的答案時,還沒有任何...因此相同的答案 – stefanB 2009-05-25 11:05:09

+0

由於對象是常量const函數將是必需的。 – siddhusingh 2013-08-12 12:50:23

0

注意const之後的參數,這是爲了讓「你的」(比較中的左側)對象爲常量。

請您詳細說明一下嗎?爲什麼如果你讓const成員(就我所知,這意味着它不能改變對象的狀態 - 例如修改私有變量)可以保證「你的」將成爲左側?

0

請您詳細說明一下嗎?爲什麼如果你讓const成員(就我所知,這意味着它不能改變對象的狀態 - 例如修改私有變量)可以保證「你的」將成爲左側?

我還沒有備受好評的評論。

const不會神奇地確保「你的」將成爲左手邊。這張海報是說左手邊(即x in x < y)是比較被調用的對象。正如你保護y的成員免受const對運算符<的影響一樣,你也希望在方法簽名結束時保護x的成員免受const的影響。