对于四种关联式容器而言,它们的模板参数中都有一个 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 stdvoid 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;
}