为什么std::set支持自由函数operator<却不支持类成员实现的operator<?
成员函数版
operator<无法适配std::set的核心原因 你实现的类成员operator<没有加const限定,无法被const修饰的类对象调用,而std::set内部比较元素时操作的全是const限定的元素,因此匹配不到可用的比较运算符,触发编译错误。
具体逻辑拆解
std::set是基于红黑树实现的有序容器,为了保证元素顺序不被破坏,容器内的元素默认不可随意修改,内部做排序比较时,拿到的操作数都是const my&类型的const对象。- C++语法规定:没有加const后缀的非const成员函数,禁止被const对象调用。你写的
bool operator<(const my other)本质是把<运算符的左操作数(也就是调用这个成员函数的对象)限定为非const的可修改对象,当左操作数是const类型的my时,这个运算符根本不会进入候选匹配列表。 - 你注释掉的自由函数版本
operator<的两个参数都是const类型,不管左右操作数是否带const限定都能正常传参调用,所以可以正常编译运行。 - STL默认用
std::less<my>作为set的比较规则,它的核心实现就是直接对两个const元素执行__x < __y操作,当找不到适配const操作数的<运算符时,就会抛出你看到的编译错误。
修正后的成员运算符写法
成员版比较运算符需要在函数末尾加const后缀,同时参数建议传const引用避免不必要的对象拷贝,示例:
class my{ public: int a; double b; my(int p){ a=p; b=0; } // 注意末尾的const,代表该函数不会修改调用方对象,允许const对象调用 bool operator> (const my& other) const { return this->a > other.a; } bool operator < (const my& other) const { return this->a < other.a; } };
替换后即可正常编译运行。
补充:你原来的实现里参数是值传递
const my other,每次比较都会触发一次对象拷贝,改成const引用传递性能更好。
内容的提问来源于stack exchange,提问作者Daniel Zaken
相关产品推荐
相关产品推荐

