对于四种关联式容器而言,它们的模板参数中都有一个
Compare
,默认采用的是std::
less
,所以如果
Key
是自定义类型,需要自己传递
Compare
类型的参数才能满足条件,否则无法通过编译。下面以自定义类型Point
为例,以点到原点的距离为标准进行比较。

改写的方式有三种:模板的特化、运算符的重载(小于符号的重载)、函数对象的写法。
#include <math.h>
#include <iostream>
#include <ostream>
#include <set>
using std::cout;
using std::endl;
using std::set;
template <typename Container>
void display(const Container &con)
{
for(auto &elem : con)
{
cout << elem << " ";
}
cout << endl;
}
class Point
{
public:
Point(int ix = 0, int iy = 0)
: _ix(ix)
, _iy(iy)
{
}
double getDistance() const
{
/* sqrt(pow(_ix, 2) + pow(_iy, 2)); */
return hypot(_ix, _iy);
}
int getX() const
{
return _ix;
}
int getY() const
{
return _iy;
}
~Point()
{
}
friend std::ostream &operator<<(std::ostream &os, const Point &rhs);
friend bool operator<(const Point &lhs, const Point &rhs);
friend struct ComparePoint;
private:
int _ix;
int _iy;
};
std::ostream &operator<<(std::ostream &os, const Point &rhs)
{
os << "(" << rhs._ix
<< ", " << rhs._iy
<< ")";
return os;
}
//小于符号的重载
bool operator<(const Point &lhs, const Point &rhs)
{
cout << "bool operator<" << endl;
if(lhs.getDistance() < rhs.getDistance())
{
return true;
}
else if(lhs.getDistance() == rhs.getDistance())
{
if(lhs._ix < rhs._ix)
{
return true;
}
else if(lhs._ix == rhs._ix)
{
if(lhs._iy < rhs._iy)
{
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
else
{
return false;
}
}
//y + n(目标行号) + G 复制
//d + n(目标行号) + G 删除
//函数对象的写法
struct ComparePoint
{
bool operator()( const Point& lhs, const Point& rhs ) const
{
cout << "bool ComparePoint" << endl;
if(lhs.getDistance() < rhs.getDistance())
{
return true;
}
else if(lhs.getDistance() == rhs.getDistance())
{
if(lhs._ix < rhs._ix)
{
return true;
}
else if(lhs._ix == rhs._ix)
{
if(lhs._iy < rhs._iy)
{
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
else
{
return false;
}
}
};
//命名空间的扩展
namespace std
{
//模板的特化
template <>
struct less<Point>
{
bool operator()(const Point &lhs, const Point &rhs) const
{
cout << "template <> struct less" << endl;
if(lhs.getDistance() < rhs.getDistance())
{
return true;
}
else if(lhs.getDistance() == rhs.getDistance())
{
if(lhs.getX() < rhs.getX())
{
return true;
}
else if(lhs.getX() == rhs.getX())
{
if(lhs.getY() < rhs.getY())
{
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
else
{
return false;
}
}
};
}//end of namespace std
void test()
{
set<Point> number = {
/* set<Point, ComparePoint> number = { */
Point(1, 2),
Point(1, -2),
Point(-1, 2),
Point(1, 2),
Point(3, 2),
};
display(number);
}
int main(int argc, char *argv[])
{
test();
return 0;
}