我有一个小程序我想执行来测试一些东西
#include <map> #include <iostream> using namespace std; struct _pos{ float xi; float xf; bool operator<(_pos& other){ return this->xi < other.xi; } }; struct _val{ float f; }; int main() { map<_pos,_val> m; struct _pos k1 = {0,10}; struct _pos k2 = {10,15}; struct _val v1 = {5.5}; struct _val v2 = {12.3}; m.insert(std::pair<_pos,_val>(k1,v1)); m.insert(std::pair<_pos,_val>(k2,v2)); return 0; }
问题是当我尝试编译它,我得到以下错误
$g++ m2.cpp -o mtest In file included from /usr/include/c++/4.4/bits/stl_tree.h:64,from /usr/include/c++/4.4/map:60,from m2.cpp:1: /usr/include/c++/4.4/bits/stl_function.h: In member function ‘bool std::less<_Tp>::operator()(const _Tp&,const _Tp&) const [with _Tp = _pos]’: /usr/include/c++/4.4/bits/stl_tree.h:1170: instantiated from ‘std::pair<typename std::_Rb_tree<_Key,_Val,_KeyOfValue,_Compare,_Alloc>::iterator,bool> std::_Rb_tree<_Key,_Alloc>::_M_insert_unique(const _Val&) [with _Key = _pos,_Val = std::pair<const _pos,_val>,_KeyOfValue = std::_Select1st<std::pair<const _pos,_val> >,_Compare = std::less<_pos>,_Alloc = std::allocator<std::pair<const _pos,_val> >]’ /usr/include/c++/4.4/bits/stl_map.h:500: instantiated from ‘std::pair<typename std::_Rb_tree<_Key,std::pair<const _Key,_Tp>,std::_Select1st<std::pair<const _Key,_Tp> >,typename _Alloc::rebind<std::pair<const _Key,_Tp> >::other>::iterator,bool> std::map<_Key,_Tp,_Alloc>::insert(const std::pair<const _Key,_Tp>&) [with _Key = _pos,_Tp = _val,_val> >]’ m2.cpp:30: instantiated from here /usr/include/c++/4.4/bits/stl_function.h:230: error: no match for ‘operator<’ in ‘__x < __y’ m2.cpp:9: note: candidates are: bool _pos::operator<(_pos&) $
我以为宣称操作者关键就是解决问题,但还是在那里.
可能是错的?
提前致谢.
解决方法
问题是这样的:
bool operator<(_pos& other)
应该是这样的:
bool operator<(const _pos& other) const { // ^^^^ ^^^^^
没有第一个const,比较的右边(b< b)不能是const,因为没有const,函数可能会修改它的参数. 没有第二个const,比较的左侧(a< b)不能是const,函数可能会修改它. 在内部,地图的关键是总是const. 应该注意,你应该更喜欢使用非成员函数.也就是说,更好的是一个自由功能:
bool operator<(const _pos& lhs,const _pos& rhs) { return lhs.xi < rhs.xi; }
与您的班级相同的命名空间. (对于我们的例子,就在它的下面)
顺便说一句,在C中,不需要使用struct将struct类型变量的声明前缀.这是完美的,而且是首选:
_pos k1 = {0,10}; _pos k2 = {10,15}; _val v1 = {5.5}; _val v2 = {12.3};
(虽然你的类型名称被公认为非正统的方式:P)
最后,您应该更喜欢make_pair实用程序功能:
m.insert(std::make_pair(k1,v1)); m.insert(std::make_pair(k2,v2));
它可以让您不必写出对的类型,而且通常更容易阅读. (特别是当更长的类型名称出现时)