STL做爲通用模板極大地方便了C++使用者的編程,由於它能夠存儲任意數據類型的元素編程
若是咱們想用set與map來存儲自定義結構體時,以下函數
struct pp { double xx; double yy; }; set<pp> aa[25]; struct ab { double aa; double bb; double cc; }stra[25]; map<ab, int> mm;
上面咱們使用 set 來存儲 pp結構體,將 ab結構體做爲一個映射的Keyspa
顯然咱們這樣作編譯器會報錯,緣由是set與map內部須要比較各個元素的大小,這樣咱們的結構體缺失了小於號的重載,沒法存儲code
改後以下:blog
struct pp { double xx; double yy; bool operator < (const pp a)const //重載小於號
{ return xx < a.xx; } }; set<pp> st; struct ab { double aa; double bb; double cc; bool operator < (const ab a)const //重載小於號
{ return aa < a.aa; } }; map<ab, int> mp;
這樣用經過結構體中的某個數比較來定義結構體的小於號,咱們的程序就編譯成功了編譯器
但在運行時咱們就會發現一個現象,那就是若是咱們編譯
將一個pp結構體模板
A(A.xx == 1, A.yy == 2)class
插入集合st以後容器
咱們若再插入一個pp結構體
B(B.xx == 1,B.yy == 3)
後面檢查時會發現,集合中只有A而沒有B,但插入insert操做是確實執行過的
那麼緣由應該只有一個,就是set內部將A與B視爲同一個元素,因爲set的去重性,第二次加入B不成功。
爲什麼會認爲A,B相同?注意到咱們的小於號重載
bool operator < (const pp a)const //重載小於號
{ return xx < a.xx; }
要知道上面咱們僅僅用pp結構體成員xx來定義小於號,因此因爲A,B的xx相同(都是1),set內部認爲A,B相同(即便A,B的yy值不相同)
相似地,咱們若是給map裏面加上兩對 「鍵-值」
而這兩個鍵(都是ab結構體)的成員aa相同而bb與cc不相同的話
咱們的mp映射裏面也會只有一對「鍵-值」,(並且值是後一個加入的值覆蓋掉了前面的值)
解決方法就是修改小於號重載函數,使得結構體成員有一個不相同時,return後面的表達式就不能相等
舉例以下
struct pp { double xx; double yy; bool operator < (const pp a)const { return xx * yy - xx / yy + yy / 2.745 < a.xx * a.yy - a.xx / a.yy + a.yy / 2.745; //用於集合的必備操做
} }; set<pp> aa[25]; struct ab { double aa; double bb; double cc; bool operator < (const ab a)const { return aa * cc / 5.123 + bb / 3.145 - aa < a.aa * a.cc / 5.123 + a.bb / 3.145 - a.aa;//用於映射的必備操做
} } map<ab, int> mm;
可看出,新的重載方式囊括告終構體內部的全部成員,而且使用了三位小數,確保了只有在兩個結構體內部成員徹底同樣時容器內部纔會判爲相同元素,出現錯誤的機率被降到極低。
因此能夠在表面現象上肯定的是,set與map內部不只用小於號來判斷元素大小,並且也用它來判斷元素是否相同
保證重載小於號的返回表達式的比較值對於不一樣元素具備真正的辨別性,是用這些容器來裝載自定義結構體所須要注意的事項