web-dev-qa-db-ja.com

std :: mapでキーとして構造体をどのように使用できますか?

次のコードがありますが、最終行でエラーが発生します。

struct coord { 
    int x, y; 

    bool operator=(const coord &o) {
        return x == o.x && y == o.y;
    }

    bool operator<(const coord &o) {
        return x < o.x || (x == o.x && y < o.y);
    }
};

map<coord, int> m;
pair<coord, int> p((coord{0,0}),123);
m.insert(p); // ERROR here

マップのキーとして構造体をどのように使用できますか?


私はコードをこれに変更しようとしました:

struct coord { 
    int x, y; 

    bool const operator==(const coord &o) {
        return x == o.x && y == o.y;
    }

    bool const operator<(const coord &o) {
        return x < o.x || (x == o.x && y < o.y);
    }
};

しかし、まだ次のエラーが発生します。

C:\ Users\tomc\Desktop\g> mingw32-make g ++ test.cpp -std = c ++ 0x c:\ mingw\bin ../ lib/gcc/mingw32/4.5.2/include /からインクルードされたファイルc ++/string:5 0:0、c:\ mingw\bin ../ lib/gcc/mingw32/4.5.2/include/c ++/bits/loc ale_classes.h:42から、c:\ mingw\binから。 ./lib/gcc/mingw32/4.5.2/include/c++/bits/ios _base.h:43、c:\ mingw\bin ../ lib/gcc/mingw32/4.5.2/include/c ++/iosから:43、c:\ mingw\bin ../ lib/gcc/mingw32/4.5.2/include/c ++/ostreamから:40、c:\ mingw\bin ../ lib/gcc/mingw32/4.5.2から/ include/c ++/iostream:40、test.cpp:1から:c:\ mingw\bin ../ lib/gcc/mingw32/4.5.2/include/c ++/bits/stl_function.h:メンバー関数 'bool std :: less <_Tp> :: operator()(const _Tp&、const _Tp&)const [with _ Tp = coord] ':c:\ mingw\bin ../ lib/gcc/mingw32/4.5.2/include/c ++/bits/stl_tree.h:1184:4:inst antiated from 'std :: pair、bool> std :: _ Rb_tree <_Key、_Val、_KeyOfValue、_Compare、_Alloc> :: _ M_insert_unique(const _Val&)[with _Key = coord 、_Val = std :: pair、_KeyOfValue = std :: _ Select1st>、_ Compare = std :: less、_Alloc = std :: alloc ator>] 'c:\ mingw\bin ../ lib/gcc/mingw32/4.5.2/include/c ++/bits/stl_map.h:501:41:inst ntiated from' std :: pair、std :: _ Select1st >、_Compare、typename _Alloc :: rebind :: value_type> :: other> :: iterator、bool> std :: map <_Key、_Tp、_Compare、_Alloc> :: insert(const std :: map <_Key、_Tp、 _Compare、_ Alloc> :: value_type&)[with _Key = coord、_Tp = int、_Compare = std :: less、_Alloc = std :: allocator>、typename std :: _ Rb_tree <_ Key、std :: pair、std: :_Select1st>、_ Compare、typename _Alloc :: rebind :: value_ty pe> :: other> :: iterator = std :: _ Rb_tree_iterator>、st d :: map <_Key、_Tp、_Compare、_Alloc> :: value_type = std ::ペア] 'test.cpp:56:12:ここからインスタンス化c:\ mingw\bin ../ lib/gcc/mingw32/4.5.2/include/c ++/bits/stl_function.h:230:22:er ror: 'const coord'を 'const bool coord :: operator <(co nst coord&)'の 'this'引数として渡すと修飾子が破棄されるmingw32-make:*** [ゲーム]エラー1

25
user181351

やってみてoperator <const

bool operator<(const coord &o)  const {

(君の = operatorはおそらく== operatorおよびconstも)

44
Andreas Brinck

はるかに簡単なのは、メンバー関数としてではなく、構造体に対してグローバルな「小なり」演算子を定義することです。

std :: mapは、デフォルトで「lessthan」ファンクタを使用します。これは、マップのキータイプに対して定義されたグローバルな「operator <」を使用します。

bool operator<(const coord& l, const coord& r) {
     return (l.x<r.x || (l.x==r.x && l.y<r.y));
}
9
haavee

answer byAndriiで述べたように、mapの代わりにカスタム比較オブジェクトを提供できます構造体にoperator<を定義します。 C++ 11 なので、比較オブジェクトを定義する代わりに lambda式 を使用することもできます。さらに、構造体がmapを機能させるためにoperator==を定義する必要はありません。その結果、構造体を次のように短く保つことができます。

struct coord {
    int x, y;
};

そして、残りのコードは次のように書くことができます:

auto comp = [](const coord& c1, const coord& c2){
    return c1.x < c2.x || (c1.x == c2.x && c1.y < c2.y);
};
std::map<coord, int, decltype(comp)> m(comp);

Ideonのコード

3
honk

サードパーティのデータ型に使用できる別の解決策は、Comparison objectを3番目のテンプレートパラメータとして渡すことです。

2
Andrii