关于c ++:如何在std :: map中使用struct作为键?

How can I use a struct as key in a std::map?

我有以下代码,但最后一行出现错误:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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

如何使用结构作为映射中的键?

我试图将代码更改为:

1
2
3
4
5
6
7
8
9
10
11
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 In file
included from
c:\mingw\bin../lib/gcc/mingw32/4.5.2/include/c++/string:5 0:0,
from
c:\mingw\bin../lib/gcc/mingw32/4.5.2/include/c++/bits/loc
ale_classes.h:42,
from
c:\mingw\bin../lib/gcc/mingw32/4.5.2/include/c++/bits/ios
_base.h:43,
from
c:\mingw\bin../lib/gcc/mingw32/4.5.2/include/c++/ios:43,
from
c:\mingw\bin../lib/gcc/mingw32/4.5.2/include/c++/ostream: 40,
from
c:\mingw\bin../lib/gcc/mingw32/4.5.2/include/c++/iostream :40,
from test.cpp:1:
c:\mingw\bin../lib/gcc/mingw32/4.5.2/include/c++/bits/stl_function.h:
In member function '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::allocator>]'
c:\mingw\bin../lib/gcc/mingw32/4.5.2/include/c++/bits/stl_map.h:501:41:
insta 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::pair]'
test.cpp:56:12: instantiated from here
c:\mingw\bin../lib/gcc/mingw32/4.5.2/include/c++/bits/stl_function.h:230:22:
er ror: passing 'const coord' as 'this' argument of 'const bool
coord::operator<(co nst coord&)' discards qualifiers mingw32-make: *** [game] Error 1


试着让operator <const

1
bool operator<(const coord &o)  const {

(你的= operator也应该是== operatorconst)


到目前为止,最简单的方法是为结构定义一个全局的"小于"运算符,而不是作为成员函数。

std::map使用-默认情况下使用"lessthan"函数,该函数反过来使用为映射的键类型定义的全局"operator<"。

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


另一种可能用于第三方数据类型的解决方案是将Comparison object作为第三个模板参数传递。例子


如andrii的答案所述,您可以为map提供自定义比较对象,而不是为您的结构定义operator<。由于C++ 11,还可以使用lambda表达式而不是定义比较对象。此外,您不需要为您的结构定义operator==,以使map工作。因此,您可以将结构保持如此短的长度:

1
2
3
struct coord {
    int x, y;
};

剩下的代码可以写如下:

1
2
3
4
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);

Ideone代码