繁体   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