【问题标题】:Overloading operator for set集合的重载运算符
【发布时间】:2014-11-20 02:36:40
【问题描述】:

我正在使用 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 中所需的

【问题讨论】:

    标签: c++ stl stdset


    【解决方案1】:

    正如您现在所拥有的,v0 中的每个组件都必须小于 v1 中的每个组件。这不是严格的弱排序。您应该一次检查一个组件。仅当您当前检查的组件相等时才检查后续组件。此外,您应该删除 epsilon。虽然这对于检查浮点计算结果的等价性很有用,但对于排序没有用,因为它也违反了严格的弱排序。最简单的方法是将operator&lt; 用于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::tie 来测试字典顺序,尽管我很确定在这种情况下设计本身存在缺陷,不应该尝试订购 3D 向量
    • @vsoftco:有时能够以某种方式订购东西很有用,即使订购标准是完全任意的。仅出于搜索目的。
    【解决方案2】:

    std::abs比较和epsilon的区别,点赞

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

    否则您可能会得到负面结果 它总是小于你的epsilon,并且规范测试会失败。

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

    【讨论】:

    • 我尝试这样做,但违反严格弱并导致运行时错误。
    • @TringVu 啊,好吧,我明白了,你不能按规范对向量进行排序,就像你不能对复数引入一个maninful ordering。你应该考虑一下不同的排序。你可以例如首先比较绝对值,然后是角度,但同样,在数学上它并没有太大意义。
    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-11
      • 1970-01-01
      • 2014-10-29
      • 2012-04-03
      • 1970-01-01
      • 2017-11-27
      相关资源
      最近更新 更多