3

我尝试使用定义为的地图:

    map<Vertex,unsigned int> _addedVertices; 

现在,当我使用 find 函数检查顶点是否已经在里面时,我得到了一个指向具有不同信息的错误顶点的迭代器,所以我尝试了以下方法:

    map<Vertex,unsigned int,cmpByVertexFields> _addedVertices; 

这没有帮助。

我在 Vertex 类中也有以下重载函数。

    bool operator<(const Vertex &otherV)const{
        return(_x<otherV._x && _y<otherV._y && _z<otherV._z);
    }
    bool operator==(const Vertex &otherV)const{
        return _x==otherV._x && _y==otherV._y && _z==otherV._z;
    }

但没有任何效果。示例:我插入了一个包含 (0.2,0.1,0.4) 的顶点,接下来我使用的是带有 (0.2,0.15,0.41) 的 find 函数,我得到的迭代器是第一个顶点而不是 map.end()。

我忘了定义什么?谢谢

编辑: cmpByVertexFields :

struct cmpByVertexFields {
    bool operator()(const Vertex& a, const Vertex& b) const {
        return a.getX()==b.getX() &&
            a.getY()==b.getY() &&
            a.getZ()==b.getZ();
    }
};
4

3 回答 3

5

这是你的罪魁祸首

bool operator<(const Vertex &otherV)const{
        return(_x<otherV._x && _y<otherV._y && _z<otherV._z);
    }

这不会产生严格的弱排序

你需要这样的东西

bool operator<(const Vertex &otherV)const{
        if(_x != otherV.x)
               return _x < otherV.x;
        if(_y != otherV.y)
               return _y < otherV.y;
        return _z < otherV.z;
    }

或者,等效且更方便的是,使用 std::tie 将它们作为元组进行比较

bool operator<(const Vertex &otherV)const{
       return std::tie(x_, y_, z_) < std::tie(OtherV.x_, OtherV.y_, OtherV.z_);
}
于 2013-07-20T11:47:57.180 回答
4

正如胡安在评论中所说,您的operator <实现在语义上是不正确的。由于您在谈论顶点,因此您实际上需要在_x,_y和之间实现字典比较_z

最简单的方法是使用std::tuple内置的比较

bool operator<(const Vertex &otherV)const{
    return std::tie(_x, _y, _z) < std::tie(otherV._x, otherV._y, otherV._z);
}

std::tie这种方式使用现在是实现跨(成员)变量的字典比较的既定方式(您实际上可以将其用于operator==实现)。

于 2013-07-20T11:47:49.657 回答
4

比较函子或小于operator<必须实现严格的弱排序。这是std::map. 你的没有。没有明显和自然的方式来排序 3D 顶点,但如果你想按字典顺序排序xy然后z坐标,那么最简单的方法是使用std::tieboost::tie或者std::tr1::tie如果你没有 C++11 支持):

bool operator<(const Vertex &otherV)const{
    return std::tie(_x, _y, _z) < std::tie(otherV._x, otherV._y, otherV._z);
}

请注意,此排序完全是任意的:为什么要x优先于y?实施适合您要解决的问题的排序取决于您。另一方面,如果您不关心地图元素的实际排序,则任何严格的弱排序都可以。

于 2013-07-20T11:48:14.580 回答