的std ::设置使用运营商的

问题描述 投票:-1回答:1

这个问题是有点儿关系到我的其他问题在这里:link(见注释的讨论)。基本上,我有以下问题:

我有一个类node。其中有一些领域,最重要的是:GHpospos是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<比较它的元素。所以n1n3具有相同G+H值并且它们被认为是相等的(在输出的第二行中的2是set`s元件的数量 - > 2,而不是3)。

之前,我知道了std::set的使用operator<的比较平等,我已经写了operator==operator!=思维组将使用其中的一个比较类的对象。但它使用的operator<

所以在这里我的问题是,为什么实际上它使用该运营商。那岂不是更容易使用operator==operator!=

对我来说,它有点复杂的工作,因为我不得不想别的办法来写operator<或使用不同的容器(因此编写lambda表达式),或者我可以使用.posoperator<比较和改写std::min_element自己(拿GH总和该帐户,而不是.pos场)

c++ stl set operator-overloading
1个回答
1
投票

你所试图实现违反Strict Weak Orderingstd::set要求。基本上,如果你有2个数字,也不是小于另一方面,它们必须是相同的!他们也不能是不同的(使用一些不同的语法检查时)。

您所有的比较操作符应该定义一致,以便有对你的类型值一个明确的想法。你的哪个成员都是突出的,即有助于价值?可能还有其他的成员,但他们不应该在比较运营商进行检查。

一个例子是std::vector。如果两个vectors都包含a, b, c,他们是平等的。他们可能有不同数额的闲置(vector.capacity())的存储空间,但这不是任一对象的价值的一部分。

如果你有时间,John Lakos has presented about thisAlexander Stepanov has written about it

© www.soinside.com 2019 - 2024. All rights reserved.