转换运算符选择规则疑问:赋值无歧义为何关系表达式有歧义?
为什么赋值表达式无歧义但关系表达式存在歧义?
先看你给出的示例代码:
#include <iostream> class MyClass { public: operator int() { return 0; } operator unsigned int() { return 1u; } }; int main() { MyClass obj; std::cout << (obj == 0); // 存在歧义 unsigned int n = obj; // 无歧义 }
先解释赋值(初始化)无歧义的原因
unsigned int n = obj; 属于拷贝初始化,目标类型明确是unsigned int。编译器会优先找能直接转成unsigned int的转换函数——也就是你的operator unsigned int(),这是精确匹配。
而operator int()虽然也能转,但转完之后还需要把int类型再转换成unsigned int,多了一步标准转换,优先级比精确匹配低,所以编译器直接选前者,不会有歧义。
再讲关系表达式有歧义的原因
obj == 0里的0是int类型,编译器要考虑两种合法的比较路径:
- 路径1:把
obj通过operator int()转成int,然后和int类型的0比较(int == int) - 路径2:把
obj通过operator unsigned int()转成unsigned int,同时把int类型的0也转成unsigned int,然后比较(unsigned int == unsigned int)
这两条路径的优先级完全一致:都是「用户自定义转换(把obj转成算术类型) + 一步标准转换(仅路径2里的0转unsigned)」。编译器没办法判断你想走哪条路,所以就报了歧义错误。
内容的提问来源于stack exchange,提问作者xiaokaoy
相关产品推荐
相关产品推荐

