无法重载 glm::vec2 '<'运算符

Failed to overload glm::vec2 '<' operator

本文关键字:lt 运算符 vec2 重载 glm      更新时间:2023-10-16

我需要将std::map与glm::vec2一起使用,所以我尝试实现'<'操作员,但它失败了。(std::map需要这个操作员)

以下是我的测试示例中的代码:

bool operator <(const glm::vec2& l, const glm::vec2& r)
{
    int lsize = l.x + l.y;
    int rsize = r.x + r.y;
    return lsize < rsize;
}

class A
{
public:
    A()
    {
        test[glm::vec2(5, 5)] = 4;
    }
private:
    std::map<glm::vec2, int> test;
};

int _tmain(int argc, _TCHAR* argv[])
{
    A a;
    return 0;
}

当我创建自己的Vector2类并以相同的方式实现运算符时,它会进行编译,但使用glm::vec2时失败(我有19个错误,告诉运算符"<"不是为glm:;vec2等定义的)

error C2676: binary '<' : 'const glm::vec2' does not define this operator or a conversion to a type acceptable to the predefined operator   

请注意,我的运算符重载函数编译时,错误来自于std::map的使用,看起来像是'<'glm::vec2运算符仍然被认为是未定义的。

以下是GLM来源,如果它可以帮助您:https://github.com/g-truc/glm/tree/master/glm

我担心的是,你甚至一开始就试图这样做,因为我认为这可能不是你真正想做的。但如果你真的想这样做,你需要把它放在正确的命名空间中。

namespace glm {
namespace detail {
// But don't do this!  This is not a good idea...
bool operator <(const glm::vec2& l, const glm::vec2& r)
{
    int lsize = l.x + l.y;
    int rsize = r.x + r.y;
    return lsize < rsize;
}
}
}

但是等一下!这是错误的

  • vec2不是有序的,所以实现<在数学上没有任何意义
  • 重写库类型上的运算符不是一个好主意
  • vec2没有被订购,所以你不应该把它们放在std::map

std::map使其内部的元素保持有序。那么,当你这样做的时候会发生什么呢?

int main(int argc, char* argv[])
{
    std::map<glm::vec2, int> m;
    m[glm::vec2(1, 1)] = 10;
    std::cout << m[glm::vec2(0, 2)] << 'n';
    return 0;
}

是的,这会打印出10,尽管我们从未将(0,2)添加到地图中。

你可能想要使用一个空间索引(例如quattree),或者至少使用一个字典顺序。除此之外,如果这是您真正想要的行为,则应该通过模板参数更改std::map上的比较器。

struct vec2_cmp {
    bool operator()(const glm::vec2 &x, const glm::vec2 &y) { ... }
}
std::map<glm::vec2, int, vec2_cmp> m;