C++ 如何在 std::map 中使用结构体作为键?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7204283/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 16:35:53  来源:igfitidea点击:

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

c++c++11stdmap

提问by Andreas Brinck

I have the following code, but I get an error on on the last line:

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

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

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

如何在地图中使用结构作为键?



I tried to change the code to this:

我试图将代码更改为:

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);
    }
};

But I'm still getting the following error:

但我仍然收到以下错误:

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

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, from 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:从'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: 从 '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 > , _ 相比,typename _Alloc::rebind::value_ty pe>::other>::iterator = std::_Rb_tree_iterator >, st d::map<_Key, _Tp, _Compare, _Alloc>::value_type = std::pair]' 测试。 cpp:56:12: 从这里实例化 c:\mingw\bin../lib/gcc/mingw32/4.5.2/include/c++/bits/stl_function.h:230:22: 错误:传递 'const coord'作为“const bool coord::operator<(const coord&)”的“this”参数丢弃限定符mingw32-make: *** [game] Error 1const bool coord::operator<(const coord&)' 丢弃限定符 mingw32-make: *** [game] Error 1const bool coord::operator<(const coord&)' 丢弃限定符 mingw32-make: *** [game] Error 1

回答by Andreas Brinck

Try and make operator <const:

尝试制作operator <const

bool operator<(const coord &o)  const {

(Your = operatorshould probably be == operatorand constas well)

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

回答by haavee

By far the simplest is to define a global "less than" operator for your struct in stead of as a member function.

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

std::map uses - by default - the 'lessthan' functor which, in turn, uses the global "operator<" defined for the key type of the map.

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));
}

回答by honk

As mentioned in the answerby Andrii, you can provide a custom comparison object to the mapinstead of defining operator<for your struct. Since C++11, you can also use a lambda expressioninstead of defining a comparison object. Moreover, you don't need to define operator==for your struct to make the mapwork. As a result, you can keep your struct as short as this:

正如提到的答案安德里,你可以提供一个自定义的比较对象的map,而不是确定的operator<为你的结构。从C++11 开始,您还可以使用lambda 表达式而不是定义比较对象。此外,您不需要operator==为您的结构定义来完成map工作。因此,您可以保持结构如此简短:

struct coord {
    int x, y;
};

And the rest of your code could be written as follows:

其余的代码可以写成如下:

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);

Code on Ideone

Ideone 上的代码

回答by Andrii

Another solution, which may be used for third-party data types, is to pass a Comparison objectas third template parameter. example

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