簡體   English   中英

std :: set使用運算符

[英]std::set use of operator<

這個問題有點和我在這里的其他問題有關: 鏈接 (請參閱評論中的討論)。 基本上,我有以下問題:

我有一個班級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< )。 這就是我想要的。 但是正如您所看到的,我創建的三個node具有不同的.pos字段(基本上是坐標)。 因此,我希望所有這些都可以一起出現。 換句話說,可以說每個節點的“唯一性”應由.pos字段確定(實際上是使用我在上面定義的該字段的operator== )。 節點之一被認為不是唯一的,因為cuz 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自己重寫std::min_element (以在帳戶中使用GH總和,而不是.pos字段)

您試圖達到的目的違反了std::set嚴格弱排序要求。 基本上,如果您有2個數字,且兩個數字都不小於另一個,則它們必須相同! 它們也不能不同(使用某些不同的語法檢查時)。

應該對所有比較運算符進行統一定義,以便對類型有明確的價值觀念。 您類型中的哪些成員是顯着的 ,即有助於價值? 可能還有其他成員,但是絕對不要在比較運算符中對其進行檢查。

一個示例是std::vector 如果兩個vector s都包含a, b, c ,則它們相等。 它們可能有不同數量的未使用存儲空間( vector.capacity() ),但這不是任何一個對象的的一部分。

如果您有時間, 約翰·拉科斯John Lakos)對此進行了介紹 ,而亞歷山大 ·斯蒂芬諾夫Alexander Stepanov)對此進行了介紹

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM