这个问题是有点儿关系到我的其他问题在这里: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
s我创建有不同的.pos
领域(基本上,坐标)。所以,我想他们都出现在了一组。换句话说,你可以说,每一个节点的“独特性”应该由.pos
场(实际使用该领域的operator==
,我在上面定义的)来确定。而其中一个节点被认为是不是唯一的辩论,因为std::set
使用operator<
比较它的元素。所以n1
和n3
具有相同G+H
值并且它们被认为是相等的(在输出的第二行中的2
是set`s元件的数量 - > 2,而不是3)。
之前,我知道了std::set
的使用operator<
的比较平等,我已经写了operator==
和operator!=
思维组将使用其中的一个比较类的对象。但它使用的operator<
。
所以在这里我的问题是,为什么实际上它使用该运营商。那岂不是更容易使用operator==
或operator!=
?
对我来说,它有点复杂的工作,因为我不得不想别的办法来写operator<
或使用不同的容器(因此编写lambda表达式),或者我可以使用.pos
在operator<
比较和改写std::min_element
自己(拿G
和H
总和该帐户,而不是.pos
场)
你所试图实现违反Strict Weak Ordering的std::set
要求。基本上,如果你有2个数字,也不是小于另一方面,它们必须是相同的!他们也不能是不同的(使用一些不同的语法检查时)。
您所有的比较操作符应该定义一致,以便有对你的类型值一个明确的想法。你的哪个成员都是突出的,即有助于价值?可能还有其他的成员,但他们不应该在比较运营商进行检查。
一个例子是std::vector
。如果两个vector
s都包含a, b, c
,他们是平等的。他们可能有不同数额的闲置(vector.capacity()
)的存储空间,但这不是任一对象的价值的一部分。
如果你有时间,John Lakos has presented about this和Alexander Stepanov has written about it。