使用std::map以glm::ivec2为键的编译错误及解决咨询
解决std::map使用glm::ivec2作为键的问题
你遇到的核心问题是自定义比较器的逻辑错误:std::map要求比较器实现严格弱序(即类似“小于”的判断逻辑,用于确定元素的排序和唯一性),但你写的cmpVecs里的operator()是在判断两个向量是否相等,这完全不符合map的要求。
正确的解决方案
方案1:实现符合严格弱序的自定义比较器
修改你的比较器结构体,先比较x坐标,x小的排在前面;如果x相等,再比较y坐标:
struct cmpVecs { bool operator()(const glm::ivec2& a, const glm::ivec2& b) const { // 严格弱序逻辑:先比x,再比y if (a.x != b.x) { return a.x < b.x; } return a.y < b.y; } }; // 定义map时指定该比较器 std::map<glm::ivec2, Chunk, cmpVecs> m_chunkDictionary;
方案2:重载glm::ivec2的<运算符
如果你不想每次定义map都手动指定比较器,可以全局重载glm::ivec2的小于运算符(注意要放在正确的命名空间里,让编译器能找到):
namespace glm { bool operator<(const ivec2& a, const ivec2& b) { if (a.x != b.x) { return a.x < b.x; } return a.y < b.y; } } // 此时直接使用默认map即可 std::map<glm::ivec2, Chunk> m_chunkDictionary;
为什么你的原比较器会报错?
std::map的底层是红黑树,依赖比较器来确定元素的排列顺序、判断元素是否重复。你的比较器返回的是a.x == b.x && a.y == b.y,这是相等判断,完全无法满足红黑树的排序需求——编译器期望的是一个能区分“a是否应该排在b之前”的逻辑,所以会抛出二进制运算符"<"未定义的错误(本质是比较器逻辑不符合要求)。
补充:关于自定义的contains函数
因为C++20之前std::map没有内置的contains方法,你的自定义实现可以这样写(确保是const成员函数):
bool contains(const glm::ivec2& key) const { return m_chunkDictionary.find(key) != m_chunkDictionary.end(); }
内容的提问来源于stack exchange,提问作者Gaida
相关产品推荐
相关产品推荐

