![](/img/trans.png)
[英]Is it safe to use operator != as operator < in a std::set?
[英]std::set use of operator<
這個問題有點和我在這里的其他問題有關: 鏈接 (請參閱評論中的討論)。 基本上,我有以下問題:
我有一個班級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`s元件的數量- > 2,而不是3)。
在我了解std::set
使用operator<
進行相等性比較之前,我已經寫過operator==
和operator!=
認為該集合將使用其中的一個來比較類的對象。 但是它使用operator<
。
所以我的問題是為什么它實際上使用此運算符。 使用operator==
或operator!=
會更容易嗎?
對我來說,這有點復雜,因為我必須考慮另一種寫operator<
或使用其他容器(因此編寫lambda)的方法,或者我可以使用.pos
在operator<
進行比較, std::min_element
自己重寫std::min_element
(以在帳戶中使用G
和H
總和,而不是.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.