setやmapのキーに自作クラスを渡す場合の方法です。
#include <map>
class Point{
public:
int x, y;
Point(){}
Point(int x, int y):x(x),y(y){}
};
int main(){
typedef std::map<Point, int> PointMap;
PointMap pmap;
return 0;
}
この時点ではエラーが出ませんが、insertを使う時にエラーが出ます。
mapはキーをソートするために比較する必要があるので、それを定義しないといけません。
#クラス同士を比較できるようにする
operator<を追加します。
特に何も考えない場合、これが一番楽です。
#include <map>
class Point{
public:
int x, y;
Point(){}
Point(int x, int y):x(x),y(y){}
bool operator<(const Point &right) const {return this->y < right.y;}
};
//クラスの外で定義するならこう
//bool operator<(const Point &left, const Point &right){return left.y < right.y;}
int main(){
typedef std::map<Point, int> PointMap;
PointMap pmap;
pmap.insert(PointMap::value_type(Point(0,0), 0));
return 0;
}
#テンプレートの引数で指定する
上記の例だとPoint型を比較できるようにしているわけですが、yの値だけで比較するものを追加するのはちょっと変です。
こういう場合は関数オブジェクトを使ってmap側に比較関数を指定します。
#include <map>
class Point{
public:
int x, y;
Point(){}
Point(int x, int y):x(x),y(y){}
};
class PointCompareY{
public:
bool operator()(const Point &left, const Point &right){return left.y < right.y;}
};
int main(){
typedef std::map<Point, int, PointCompareY> PointMap;
PointMap pmap;
pmap.insert(PointMap::value_type(Point(0,0), 0));
return 0;
}
#コンストラクタで指定する
ラムダ式使わないと死ぬ死ぬ病だとか、実行時に比較関数を渡したい場合はmapのコンストラクタで比較関数を指定します。
#include <map>
class Point{
public:
int x, y;
Point(){}
Point(int x, int y):x(x),y(y){}
};
int main(){
typedef std::map<Point, int, bool(*)(const Point &left, const Point &right)> PointMap;
PointMap pmap([](const Point &left, const Point &right){return left.y < right.y;});
// ラムダ式ならこっちのほうがスッキリ?
// auto f = [](const Point &left, const Point &right){return left.y < right.y;};
// typedef std::map<Point, int, decltype(f) > PointMap;
// PointMap pmap(f);
pmap.insert(PointMap::value_type(Point(0,0), 0));
return 0;
}