C++ 为向量设置 keyCompare 函数

C++ set keyCompare function for vector

我将 glm::ivec3 个密钥存储在一个集合中。由于此类型缺少 keyCompare 函数,因此我在结构中定义了它。如果我只有两个数字 a,b 我可以简单地写 a < b;但是我怎么能为矢量做呢?

我尝试了以下方法:

struct KeyCompare
{
    bool operator()(const glm::ivec3& a, const glm::ivec3& b)const
    {
        return a.x < b.x && a.y < b.y && a.z < b.z;
    }
};

typedef set<glm::ivec3, KeyCompare> ChunkSet;

现在我可以插入值了,但是当检查一个值是否存在时它返回 true 而没有插入这个键。

你知道向量是如何比较的吗?

提前致谢!

你可以试试

return a.x < b.x || (a.x == b.x && a.y < b.y) || (a.x == b.x && a.y == b.y && a.z < b.z);

初始实施的问题是以下向量看起来相等,因为 !(a < b) && !(b < a) 为该实施持有:

(3, 7, 12), (4, 6, 12)

比较器必须实现 strict weak ordering. Yours doesn't. An easy way to implement that is using std::tie:

#include <tuple>
struct KeyCompare
{
  bool operator()(const glm::ivec3& a, const glm::ivec3& b)const
  {
    return std::tie(a.x, a.y, a.z) < std::tie(b.x, b.y, b.z);
  }
};

这将执行 x、y 和 z 的字典顺序比较。

您需要一个比较函数来定义键集 (ivec) 上的 order。最常见的选择是所谓的 lexicographic 顺序(用于在词典中对单词进行排序的顺序),即首先比较 x 坐标,然后是 y,然后是 z:

struct KeyCompare {
    bool operator()(const glm::ivec3& a, const glm::ivec3& b)const
    {
        if(a.x < b.x) {
           return true;
        }
        if(a.x > b.x) {
          return false;
        }
        // Here, a.x = b.x, let's compare the y's
        if(a.y < b.y) {
           return true;
        }
        if(a.y > b.y) {
           return false;
        }
        // Here, a.x = b.x and a.y = b.y, let's compare the z's
        return (a.z < b.z);
    }
};