1.隻有重載<的類或者結構才能作為map的key值。
string可以作為key值是因為string重載了<
2.如果不重載<會提示如下錯誤:
error C2676: 二進制“<”: “const C”不定義該運算符或到預定義運算符可接收的類型的轉換
3.重載<但是沒有實作會提示如下錯誤:
Expression: invalid operator<
比如bool operator < (const C &c) const{return true;}
<a></a>
#include <string>
#include <map>
using namespace std;
// 重載<的類或結構才能作為map的key值
class C
{
public:
int i;
string str;
bool operator < (const C &c) const
{
return i < c.i;
}
};
void main()
map<C,int> mapC;
C c0;
c0.i = 0;
c0.str = "str1";
mapC.insert(pair<C,int>(c0,0));
C c1;
c1.i = 1;
c1.str = "str2";
mapC.insert(pair<C,int>(c1,1));
if(c0 < c1)
int iVal = mapC[c1];
// string可以作為map的key,因為重載了<
string str1 = "str1",str2 = "str2";
if(str1 < str2) // "str2"是大于"str1"的
int n = 0;
}
/* 如果不重載<會提示如下錯誤:
* error C2676: 二進制“<”: “const C”不定義該運算符或到預定義運算符可接收的類型的轉換
* 重載<但是沒有實作會提示如下錯誤:
* Expression: invalid operator<
* 比如bool operator < (const C &c) const{return true;}
*/
補充:C++運算符重載
運算符重載的基礎就是運算符重載函數。是以今天主要講的是運算符重載函數。
1.運算符重載是對已有的運算符賦予多重含義,使同一個運算符作用域不同類型的資料導緻不同行為的發生。比如
<a href="http://www.cnblogs.com/CaiNiaoZJ/archive/2011/08/12/2136598.html"></a>
在這個程式裡"+"既完成兩個整形數的加法運算,又完成了雙精度型的加法運算。為什麼同一個運算符"+"可以用于完成不同類型的資料的加法運算?這是因為C++針對預定義基本資料類型已經對"+"運算符做了适當的重載。在編譯程式編譯不同類型資料的加法表達式時,會自動調用相應類型的加法運算符重載函數。但是C++中所提供的預定義的基本資料類型畢竟是有限的,在解決一些實際的問題時,往往需要使用者自定義資料類型。比如高中數學裡所提到的複數:
假如我們建立兩個複數,并用"+"運算符讓它們直接相加:
那麼會提示沒有與這些操作數比對的 "+" 運算符的錯誤。這是因為Complex類類型不是預定義類型,系統沒用對該類型的資料進行加法運算符函數的重載。C++就為運算符重載提供了一種方法,即運算符重載函數。其函數名字規定為operator後緊跟重載運算符。比如:operator+(),operator*()等。現在我們給上述程式聲明一個加法運算符的重載函數用于完成複數的加法運算:
View Code
結果:
在上述示例代碼中,調用運算符重載函數時,也可以以operator+(com1,com2)的形式來調用,實際上com1+com2在程式解釋時也是轉化成前者一樣的形式。但是直接用com1+com2的形式更加符合人的書寫習慣。
2.上述示例中的運算符重載函數是不屬于任何的類,是全局的函數。因為在Complex類(複數類)中的資料成員是公有的性質,是以運算符重載函數可以通路。但如果定義為私有的呢,那該怎麼辦。其實,在實際的運算符重載函數聲明當中,要不定義其為要操作類的成員函數或類的友元函數。
(1)運算符重載函數作為類的友元函數的形式:
class 類名
{
friend 傳回類型 operator運算符(形參表);
}
類外定義格式:
傳回類型 operator運算符(參數表)
函數體
友元函數重載雙目運算符(有兩個操作數,通常在運算符的左右兩則),參數表中的個數為兩個。若是重載單目運算符(隻有一個操作數),則參數表中隻有一參數。
i.友元函數重載雙目運算符(+):
ii.友元函數重載單目運算符(++):
運算符重載函數可以傳回任何類型,甚至是void,但通常傳回類型都與它所操作的類類型一樣,這樣可以使運算符使用在複雜的表達式中。比如把上述雙目運算符重載函數示例代碼中main()主函數裡的com1+com2改為com1+com2+com2,那麼結果又會不一樣了。像指派運算符=、下标運算符[]、函數調用運算符()等是不能被定義為友元運算符重載函數。同一個運算符可以定義多個運算符重載函數來進行不同的操作。
(2)運算符重載函數作為類的成員函數的形式:
傳回類型 operator 運算符(形參表);
類外定義格式:
傳回類型 類名:: operator 運算符(形參表)
函數體;
對于成員函數重載運算符而言,雙目運算符的參數表中僅有一個參數,而單目則無參數。同樣的是重載,為什麼和友元函數在參數的個數上會有所差別的。原因在于友元函數,沒有this指針。
i.成員函數重載雙目運算符(+):
對于雙目運算符而言,運算符重載函數的形參中僅為一個參數,它作為運算符的右操作數(如com2對象),而目前對象作為左操作數(如:上述中的com1對象),它是通過this指針隐含傳遞給成員運算符重載函數的。
ii.成員函數重載單目運算符(++):
對于單目運算符而言,目前對象作為運算符的操作數。
在運算符重載運用時應該注意以下幾個問題:(1)C++中隻能對已有的C++運算符進行重載,不允許使用者自己定義新的運算符;(2)C++中絕大部分的運算符可重載,除了成員通路運算符.,成員指針通路運算符.*,作用域運算符::,長度運算符sizeof以及條件運算符?:;(3)重載後不能改變運算符的操作對象(操作數)的個數。如:"+"是實作兩個操作數的運算符,重載後仍然為雙目運算符;(4)重載不能改變運算符原有的優先級;(5)重載不能改變運算符原有結合的特性。比如:z=x/y*a,執行時是先做左結合的運算x/y,重載後也是如此,不會變成先做右結合y*a;(6)運算符重載不能全部是C++中預定義的基本資料,這樣做的目的是為了防止使用者修改用于基本類型資料的運算符性質;(7)從上述的示例中可以看到雙目運算符可以被重載為友元函數也可以重載為成員函數,但有一種情況,隻能使用友元函數,是什麼情況呢?我舉個例子:
如果我們把上述main()主函數實作部分裡的total=com1+5改為total=5+com1;那麼程式就會報錯(沒有與這些操作數比對的 "+" 運算符),因為左操作數5不是該複數類的對象,不能調用相應的成員函數Complex operator+(int x),是以編譯錯誤。但如果我們定義一下兩個友元函數就能解決上述的問題:
friend Complex operator+(Complex com1,int x);
friend Complex operator+(int x,Complex com1);
3.最後還是一樣,我将用一個示例來總結一下今天所講的内容(開發工具:vs2010):
本文轉自wenglabs部落格園部落格,原文連結:http://www.cnblogs.com/greatverve/archive/2012/11/05/cpp-class-map-key.html,如需轉載請自行聯系原作者