如何让编译器优先选择类内重载的operator==而非模板operator==
问题原因
你遇到的问题核心是类内成员operator==没有添加const修饰符,导致const左操作数场景下成员重载直接被排除在候选集外,编译器只能匹配全局模板版本:
- 非静态成员函数默认隐式携带的
this指针是非常量类型,你的bool operator==(const Obj& rhs)要求左操作数必须是非常量的Obj对象才能调用。 - 当左操作数为
const Obj&类型时,成员operator==不匹配调用要求,直接被重载决议筛掉,适配任意参数的全局模板就会被选中。
你测试结果里的四行输出正好对应这个逻辑:
cmp(a)/cmp(b)中的参数都是const Obj&,成员重载不匹配,调用模板a == b中a是非常量Obj,成员重载匹配,调用类内版本b == a中b是const Obj&,成员重载不匹配,调用模板
修复方案
只要给类内的operator==添加const修饰符即可,非模板函数的重载优先级天然高于模板函数,只要类型匹配就会优先调用类内版本:
struct Obj { std::int32_t a; // 加const修饰,允许const左操作数调用 bool operator==(const Obj& rhs) const { std::cout << "Obj == " << std::endl; return a == rhs.a; } };
修改后运行测试代码,所有比较都会优先调用类内重载版本。
如果需要支持operator==的对称调用(比如左操作数为其他可转换为Obj的类型),也可以把operator==定义为全局友元函数,优先级和const成员版本一致:
struct Obj { std::int32_t a; friend bool operator==(const Obj& lhs, const Obj& rhs) { std::cout << "Obj == " << std::endl; return lhs.a == rhs.a; } };
内容的提问来源于stack exchange,提问作者Patrick
相关产品推荐
相关产品推荐

