簡體   English   中英

運算符 < std::set::insert 的重載未按預期工作

[英]operator< overload for std::set::insert not working as expected

我正在嘗試實現一個std::set::insert ,這樣它將“插入”一個結構,因為該結構尚不存在。

我為“小於”( < )添加了所需的自定義運算符重載; 然而,當代碼被執行時,它似乎只是跳過它並且不能按預期工作。 (修改的實現(添加的const noexcept取自此處: C2676: binary '<': 'const _Ty' 未定義此運算符或轉換為預定義運算符可接受的類型

示例代碼:

#include <set>

struct Coordinate
{
int x;
int y;

Coordinate(int x = 0, int y = 0) : x(x), y(y)
{
}

bool operator==(const Coordinate& obj)
{
    return x == obj.x && y == obj.y;
}

bool operator!=(const Coordinate& obj)
{
    return x != obj.x && y != obj.y;
}

bool operator< (const Coordinate& obj) const noexcept
{
    return x < obj.x && y < obj.y;
}
};

int main(){
std::set<Coordinate> current_set = {Coordinate(1, 2)};

Coordinate new_coordinate(1, 3);

current_set.insert(new_coordinate);
}

需要明確的是,通過此實現,即使成員明顯不同,該集合也不會使用new_coordinate object 進行更新。

對此的任何幫助將不勝感激。

std::set而言,您對operator<的實現不正確。 它不滿足嚴格弱排序的要求。

將其更改為:

bool operator<(const Coordinate& obj) const noexcept
{
    if ( x != obj.x )
    {
       return x < obj.x;
    }
    return y < obj.y;
}

您可以使用std::tie來簡化它。

bool operator<(const Coordinate& obj) const noexcept
{
    return std::tie(x, y) < std::tie(obj.x, obj.y);
}

std::set - cppreference.com說:

用不精確的術語來說,如果兩個對象 a 和 b 的比較都不小於另一個,則認為兩個對象是等價的:,comp(a, b) &&.comp(b, a)。

兩個對象Coordinate(1, 2)Coordinate(1, 3)的成員x都是 1,因此operator<不能為真,因此它們被認為是相同的。

常用的實現會是這樣的:

  • 如果Ax < Bx ,則A < B為真
  • 如果AX > BxA < B為假(因為B < A為真)
  • Ax == Bx , A < B當且僅當Ay < By
bool operator< (const Coordinate& obj) const noexcept
{
    return x < obj.x || (x == obj.x && y < obj.y);
}

為了補充解釋問題的其他答案:這是 class 的 C++20 版本:

struct Coordinate
{
    int x;
    int y;
    
    friend auto
    operator<=>(const Coordinate&, const Coordinate&) = default;
};

int main()
{
    std::set<Coordinate> current_set = {{1, 2}};
    current_set.emplace(1, 3);
}

暫無
暫無

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

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