设置的重载运算符

Overloading operator for set

本文关键字:运算符 重载 设置      更新时间:2023-10-16

我正在使用std::set来实现特定的算法。 该集合中有重复项,因此我认为我必须使运算符重载。重载如下所示。

class Vec3f {
    ...
    bool operator () ( const Vector3f& v0, const Vector3f& v1 ) const {
    float epsilon = 1e-7;
    return ((v1[0] - v0[0]) > epsilon) &&  ((v1[1] - v0[1]) > epsilon) && ((v1[2] - v0[2]) > epsilon);
}       ...

"Vec3f.h"
int main(){
    ...
    std::set<Vec3f,Vec3f> visited;
    ...
}

我重载了它,所以我可以使用 std::set 中所需的<运算符。>

正如您现在所拥有的,v0中的每个组件都需要小于v1中的每个组件。这不是严格的弱排序。 您应该一次检查一个组件。仅当您当前检查的组件相等时,才检查后续组件。另外,您应该放下 epsilon。虽然这对于检查浮点计算结果的等价性很有用,但对于排序没有用,因为它也违反了严格的弱排序。最简单的方法是使用 operator< 进行std::tuple

return std::tie(v0[0], v0[1], v0[2]) < std::tie(v1[0], v1[1], v1[2]);

否则,如果要手动实现,则如下所示:

if (v0[0] < v1[0]) return true;
if (v0[0] > v1[0]) return false;
if (v0[1] < v1[1]) return true;
if (v0[1] > v1[1]) return false;
if (v0[2] < v1[2]) return true;
if (v0[2] > v1[2]) return false;
return false;

使用std::abs来比较与epsilon的差异,例如

if(std::abs(v1[0]-v0[1]) > epsilon && ...){...} // not zero

否则,您可能会得到阴性结果它将始终小于您的epsilon,并且范数测试将失败。

PS:一般来说,尝试对向量进行排序是一个坏主意,因为没有直观的数学运算,您可能会遇到很多奇怪和违反直觉的情况。

你提到你只是想使用一个集合,不一定是需要排序的集合的实现。您可以考虑使用 std::unordered_set ,它不需要您定义排序,只需要定义哈希/相等函数。