LoginSignup
15
16

More than 5 years have passed since last update.

setやmapのキーに任意のクラスを渡す

Last updated at Posted at 2015-07-07

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;
}
15
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
16