自定义Point结构体重载<运算符,std::set::insert报operator<不匹配错误
为什么std::set存储自定义Point结构体时operator<匹配失败?
我想用std::set存储自定义的Point结构体,参考示例重载了<运算符,结构体代码如下:
#include <set> struct Point { float x; float y; float z; inline bool operator < (const Point& other) { return std::tie(x, y, z) < std::tie(other.x, other.y, other.z); } };
插入实例的代码:
int main(int argc, char* argv[]) { std::set<Point> points; Point point; point.x = 0.1f; point.y = 0.2f; point.z = 0.3f; points.insert(point); return 0; }
编译时出现错误:
/usr/include/c++/13/bits/stl_function.h:408:20: error: no match for ‘operator<’ (operand types are ‘const Point’ and ‘const Point’) 408 | { return __x < __y; } | ~~~~^~~~~
为什么会提示operator<不匹配?是运算符重载写法有误,还是和const实例有关?
问题原因与解决方案
错误的核心是你的operator<没有被声明为const成员函数。
std::set内部存储的元素是不可修改的(逻辑上的const),当它需要比较元素时,会以const Point对象的身份调用<运算符。而你重载的operator<没有const限定,意味着这个函数可以修改当前对象的成员变量,C++不允许用const对象调用非const成员函数,因此编译器找不到匹配的运算符。
修正后的代码
只需要给operator<添加const限定即可,同时注意显式包含std::tie所需的头文件:
#include <set> #include <tuple> struct Point { float x; float y; float z; inline bool operator < (const Point& other) const // 添加const限定 { return std::tie(x, y, z) < std::tie(other.x, other.y, other.z); } };
补充说明
std::tie属于<tuple>头文件,显式包含能避免因间接包含导致的编译隐患。- 将成员函数声明为const,是在告诉编译器:这个函数不会修改当前对象的任何成员变量,因此const对象也可以安全调用它。
内容的提问来源于stack exchange,提问作者Bakefish
相关产品推荐
相关产品推荐

