測試時用的代碼是這樣的:
#include<iostream>
#include<set>
using namespace std;
class MyType
{
public:
int a, b, c;
MyType(int a, int b, int c):a(a), b(b), c(c){}
bool operator<(const MyType& myType) const
{
return a<myType.a;
}
};
int main()
{
set<MyType> se;
MyType type1(1,2,3);
MyType type2(1,2,4);
se.insert(type1);
se.insert(type2);
cout<<"The set size:"<<se.size()<<endl;
cout<<"Elements in the set as follows:"<<endl;
for(set<MyType>::iterator it = se.begin(); it != se.end(); it++)
{
cout<<"("<<it->a<<", "<<it->b<<", "<<it->c<<") ";
}
cout<<endl;
return 0;
}
結果很明顯,當我已經把MyType(1,2,3)放到set中之後,就不能把MyType(1,2,4)放進去了。但是為什麼呢?這兩個對象看起來確實不一樣啊!STL在比較是否相同的時候不是要比較每一個數據成員的嗎?從上述的例子中,看到的確實不是這樣的,STL不會自動的做任何比較,它僅對你說明過的動作干一些指定的活兒。在重載“<”的時候,當只指定眾多數據成員中的一部分的時候,如果這部分都相同的話,set就認為是同一個元素了。就如上述所示一樣,重載的時候僅作了a的比較,而沒有說明如果a相同的話,是否對剩下的元素進行比較。這樣一來,set認為MyType(1,2,3)和MyType(1,2,4)是一樣的。要讓set正確的進行大小的比較,針對自定義類型,就必須說明所有的數據成員的比較情況。如上述的例子的“<”重載,應該這樣寫:
bool operator<(const MyType& myType) const
{
return a<myType.a?true:(b<myType.b?true:c<myType.c);
}
這樣一來,就完全說明了每一個數據成員的比較關系,set就可以正常工作了。還是MyType(1,2,3)、MyType(1,2,4)兩個元素,這回運行的結果如下:
運行代碼為:
#include<iostream>
#include<set>
using namespace std;
class MyType
{
public:
int a, b, c;
MyType(int a, int b, int c):a(a), b(b), c(c){}
bool operator<(const MyType& myType) const
{
return a<myType.a?true:(b<myType.b?true:c<myType.c);
}
};
int main()
{
set<MyType> se;
MyType type1(1,2,3);
MyType type2(1,2,4);
se.insert(type1);
se.insert(type2);
cout<<"The set size:"<<se.size()<<endl;
cout<<"Elements in the set as follows:"<<endl;
for(set<MyType>::iterator it = se.begin(); it != se.end(); it++)
{
cout<<"("<<it->a<<", "<<it->b<<", "<<it->c<<") ";
}
cout<<endl;
return 0;
}
摘自 Martin's Tips