【发布时间】:2019-02-07 20:35:25
【问题描述】:
这个问题与我在这里的另一个问题有点相关:link(参见 cmets 中的讨论)。基本上,我遇到了以下问题:
我有一堂课node。其中有一些字段,最重要的是:G、H 和 pos(pos 是 Qt 的 QPoint,但为了示例,我已经将其重写为我自己的类 Point。请看下面的例子:
#include <algorithm>
#include <iostream>
#include <memory>
#include <set>
class Point
{
public:
int _x, _y;
Point() : _x(0), _y(0) {}
Point(int x, int y) : _x(x), _y(y) {}
bool operator==(const Point& p) const { return _x == p._x && _y == p._y; }
bool operator!=(const Point& p) const { return _x != p._x && _y != p._y; }
};
class node
{
public:
node() {}
node(const Point& p) : pos(p) {}
bool operator==(const node& o) const { return pos == o.pos; }
bool operator==(const Point& o) const { return pos == o; }
bool operator!=(const node& o) const { return pos != o.pos; }
bool operator<(const node& o) const { return G + H < o.G + o.H; }
Point pos;
std::shared_ptr<node> parent;
int G = 0;
int H = 0;
};
int main()
{
node n1(Point(6, 7));
n1.G = 1;
n1.H = 1;
node n2(Point(1, 1));
n2.G = 2;
n2.H = 2;
node n3(Point(2, 2));
n3.G = 1;
n3.H = 1;
std::set<node> nodes;
nodes.insert(n1);
nodes.insert(n2);
nodes.insert(n3);
auto min = (*std::min_element(nodes.begin(), nodes.end())).pos;
std::cout << min._x << " " << min._y << '\n';
std::cout << nodes.size() << '\n';
}
这个程序的输出是:
>main.exe
6 7
2
所以搜索最低元素是成功的(使用operator<)。所以这就是我想要的。但正如你所看到的,我创建的三个nodes 有不同的.pos 字段(基本上是坐标)。所以我希望他们所有人都出现在一个集合中。换句话说,你可以说每个节点的“唯一性”应该由.pos字段决定(实际上是使用这个字段的operator==,我上面定义的)。其中一个节点被认为不是唯一的,因为std::set 使用operator< 比较其元素。所以n1 和n3 具有相同的G+H 值并且它们被认为是相等的(输出第二行中的2 是集合元素的数量-> 2,而不是3)。
在我知道std::set 使用operator< 来比较相等之前,我已经写了operator== 和operator!=,认为该集合将使用其中一个来比较我班级的对象。但它使用operator<。
所以我的问题是为什么它实际上使用这个运算符。使用operator==或operator!=不是更方便吗?
对我来说,这有点让工作复杂化,因为我必须想出另一种方法来编写 operator< 或使用不同的容器(因此编写 lambda),或者我可以使用 .pos 比较 operator< 并重写 @ 987654352@本人(取G和H在账户中的总和,而不是.pos字段)
【问题讨论】:
-
std::set 实现为二叉树 - 这要求您能够比较小于关系的条目。
-
哦,这可以解释很多。实际上不知道为什么我的问题被某人否决了,但仍然,谢谢!
-
顺便说一句:您的
operator!=应该使用||而不是&&。 -
严格来说
std::set是如何实现的并不重要,集合中的元素是排序的,你不能只使用==和!=对元素进行排序,你需要< -
所以在这种情况下,我必须手动搜索最低元素或相等检查(检查元素是否已存在于容器中):(
标签: c++ stl set operator-overloading