为std::map重载glm::vec2的<运算符失效问题求助
解决glm::vec2作为std::map键时的C2678错误
嘿,这个问题我太熟了!你碰到的C2678错误,核心原因是std::map作为有序关联容器,要求它的键类型必须支持<运算符来实现元素排序,但GLM库的glm::vec2默认并没有提供这个运算符的重载,所以编译器在xstddef里找不到合适的重载版本,直接报错了。
下面给你两种靠谱的解决办法,按需选就行:
方法一:重载全局的<运算符
直接给glm::vec2实现一个符合严格弱序要求的<运算符重载,注意要保证参数都是const引用,而且最好放在全局命名空间或者GLM的命名空间里(让编译器能通过ADL找到它):
#include <glm/glm.hpp> // 全局命名空间下的重载 bool operator<(const glm::vec2& lhs, const glm::vec2& rhs) { // 先比较x分量,x更小则整体更小;x相等时再比较y分量 if (lhs.x != rhs.x) { return lhs.x < rhs.x; } return lhs.y < rhs.y; }
这样之后,你就能正常声明std::map<glm::vec2, YourDataType>来使用了。
方法二:给std::map传自定义比较器
如果你不想污染全局命名空间(比如项目里有其他地方需要不同的vec2比较逻辑),可以给std::map指定一个自定义的比较结构体:
#include <glm/glm.hpp> #include <map> // 自定义比较器结构体 struct Vec2Comparator { // 必须是const成员函数,因为std::map会用const实例调用它 bool operator()(const glm::vec2& lhs, const glm::vec2& rhs) const { if (lhs.x != rhs.x) { return lhs.x < rhs.x; } return lhs.y < rhs.y; } }; // 声明map时传入比较器类型 std::map<glm::vec2, YourDataType, Vec2Comparator> my_voxel_map;
重要提醒
不管用哪种方法,你的比较逻辑必须满足严格弱序:
- 不能只比较x或者只比较y,否则不同的vec2(比如
(1,2)和(1,3))会被当成同一个键,导致数据覆盖 - 要保证
a < b、b < a不能同时为真,且a < b和b < c能推出a < c
内容的提问来源于stack exchange,提问作者Albanninou
相关产品推荐
相关产品推荐

