我试图在C ++ 11中编译这段代码,它给了我编译错误:
#include <iostream>
#include <unordered_set>
using namespace std;
class Point{
int x,y;
public:
Point(int a=0, int b=0): x(a), y(b) {};
int getX(void){ return x;}
int getY(void){ return y;}
};
class monkeyHash{
public:
size_t operator()(const Point & xy){
size_t h1 = std::hash<int>()(xy.getX());
size_t h2 = std::hash<int>()(xy.getY());
return (h1 ^ (h2<<1));
}
};
struct monkeyEquals{
bool operator()(const Point & lhs, const Point & rhs){
return (lhs.getX() == rhs.getX()) && (lhs.getY() == rhs.getY());
}
};
int main(){
unordered_set<Point,monkeyHash,monkeyEquals> visited;
visited.insert(Point(0,0));
}
我得到的错误消息很长,所以我将总结一下:
In member function ‘size_t monkeyHash::operator()(const Point&)’:
monkey.cpp:26:50: error: passing ‘const Point’ as ‘this’ argument of ‘int Point::getX()’ discards qualifiers [-fpermissive]
monkey.cpp:27:50: error: passing ‘const Point’ as ‘this’ argument of ‘int Point::getY()’ discards qualifiers [-fpermissive]
monkey.cpp: In member function ‘bool monkeyEquals::operator()(const Point&, const Point&)’:
它似乎也抱怨我的哈希函数。我的哈希方式是不正确的? 我仍然是模板,c ++ 11和STL的新手,很抱歉,如果这个问题很无聊。
答案 0 :(得分:1)
声明那些方法const
:
int getX(void) const { return x; }
int getY(void) const { return y; }
像这样使用const
告诉编译器该方法不会更改类实例。只有这样你才能在const Point
对象上调用它。
在C ++ 11中,你可能还想标记它们noexcept
,(例如int getX() const noexcept { return x; }
,因为它们不会抛出任何异常。如果你标记它们noexcept
,编译器可能会更多地优化您的代码。
size_t monkeyHash::operator()(const Point &)
和bool monkeyEquals::operator()(const Point &, const Point &)
方法也是如此。
PS:如果您在monkeyEquals
中重载operator==
,则可以摆脱class Point {}
课程:
inline bool operator==(const Point & rhs) const noexcept
{ return (x == rhs.x) && (y == rhs.y); }
您还可以覆盖operator!=
:
inline bool operator!=(const Point & rhs) const noexcept
{ return (x != rhs.x) || (y != rhs.y); }
请参阅this wikipedia article,了解如何在命名空间std
中编写更好的自定义哈希函数。
如果您接受此post-scriptum中的建议,您可以像这样声明容器:
unordered_set<Point> visited;