std::set::insert 的运算符< 重载未按预期工作
operator< overload for std::set::insert not working as expected
我正在尝试实现一个 std::set::insert
,这样它将 'insert' 一个结构,因为它还不存在。
我已经为 'less than' 添加了所需的自定义运算符重载 (<
);然而,当代码被执行时,它似乎只是跳过它而没有按预期工作。 (修改的实现(const noexcept
的添加取自此处:)
示例代码:
#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
对象进行更新。
如有任何帮助,我们将不胜感激。
您对 operator<
的实施对于 std::set
的目的是不正确的。不符合strictly weak ordering.
的要求
改为:
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 说:
In imprecise terms, two objects a and b are considered equivalent if neither compares less than the other: !comp(a, b) && !comp(b, a).
Coordinate(1, 2)
和Coordinate(1, 3)
两个对象的成员x
都是1,所以operator<
不可能为真,因此认为它们相同。
常用的实现是这样的:
A < B
如果 A.x < B.x
为真
A < B
为假(因为 B < A
为真)如果 A.X > B.x
- 当
A.x == B.x
、A < B
当且仅当 A.y < B.y
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);
}
我正在尝试实现一个 std::set::insert
,这样它将 'insert' 一个结构,因为它还不存在。
我已经为 'less than' 添加了所需的自定义运算符重载 (<
);然而,当代码被执行时,它似乎只是跳过它而没有按预期工作。 (修改的实现(const noexcept
的添加取自此处:
示例代码:
#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
对象进行更新。
如有任何帮助,我们将不胜感激。
您对 operator<
的实施对于 std::set
的目的是不正确的。不符合strictly weak ordering.
改为:
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 说:
In imprecise terms, two objects a and b are considered equivalent if neither compares less than the other: !comp(a, b) && !comp(b, a).
Coordinate(1, 2)
和Coordinate(1, 3)
两个对象的成员x
都是1,所以operator<
不可能为真,因此认为它们相同。
常用的实现是这样的:
A < B
如果A.x < B.x
为真
A < B
为假(因为B < A
为真)如果A.X > B.x
- 当
A.x == B.x
、A < B
当且仅当A.y < B.y
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);
}