这个问题有点和我在这里的其他问题有关:link(请参阅评论中的讨论)。基本上,我有以下问题:
我有一个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<
)。这就是我想要的。但是正如您所看到的,我创建的三个node
具有不同的.pos
字段(基本上是坐标)。因此,我希望所有这些都可以一起出现。换句话说,您可以说每个节点的“唯一性”应由.pos
字段确定(实际上是使用我在上面定义的该字段的operator==
)。节点之一被认为不是唯一的,因为cuz std::set
使用operator<
来比较其元素。因此n1
和n3
具有相同的G+H
值,它们被认为是相等的(输出第二行中的2
是set的元素数-> 2,而不是3)。
在我知道std::set
使用operator<
进行相等性比较之前,我写过operator==
和operator!=
认为该集合将使用其中的一个比较我班上的对象。但是它使用operator<
。
所以我的问题是为什么它实际上使用此运算符。使用operator==
或operator!=
会更容易吗?
对我来说,这有点复杂,因为我必须考虑另一种写operator<
或使用其他容器(因此编写lambda)的方法,或者我可以使用.pos
在{{ 1}}并自己重写operator<
(在帐户中获取std::min_element
和G
的总和,而不是H
字段)
答案 0 :(得分:1)
您试图实现的目标违反了std::set
的{{3}}要求。基本上,如果您有2个数字,且两个数字都不小于另一个,则它们必须相同!它们也不能不同(当使用某些不同的语法检查时)。
应该对所有比较运算符进行统一定义,以便为您的类型明确定义 value 。您类型中的哪些成员是“ 显着”,即对价值有所贡献?可能还有其他成员,但是绝对不要在比较运算符中对其进行检查。
一个示例是std::vector
。如果两个vector
都包含a, b, c
,则它们相等。它们可能有不同数量的未使用存储空间(vector.capacity()
),但这不是任何一个对象的 value 的一部分。
如果有时间,请Strict Weak Ordering和John Lakos has presented about this。