为何向bool转换需额外步骤时C++函数调用仍存在歧义?
重载调用歧义的原因解析
你之所以遇到这个歧义问题,是因为误解了C++重载决议中用户定义转换序列的比较规则。核心点在于:两个候选函数的转换路径虽然步数不同,但依赖的是完全独立的用户定义转换,编译器无法判定孰优孰劣。
拆解两个转换路径
- 调用
foo(Wrapper):需要把Foo直接转换成Wrapper,仅通过Wrapper的转换构造函数完成一次用户定义转换,没有后续额外转换。 - 调用
foo(bool):需要先把Foo转换成函数指针fptr_t(通过Foo的转换运算符完成用户定义转换),再把函数指针隐式转换成bool(标准转换),总共两步。
为什么无法区分优劣?
C++对用户定义转换序列的优劣判定有严格限制:
只有当两个转换序列使用了同一个用户定义转换函数或构造函数时,才会进一步比较后续的标准转换(比如一个后续是精确匹配,另一个是标准转换,前者更优)。
但你的代码中,两个转换序列依赖的是完全不同的用户定义转换逻辑:一个是Wrapper的构造函数,另一个是Foo的转换运算符。这两个转换之间没有优先级关系,编译器无法判断哪一个更符合调用意图。
你提到的cppreference规则(不涉及指针转bool的转换更优),仅适用于纯标准转换序列之间的比较,完全不适用这种包含不同用户定义转换的场景。
内容的提问来源于stack exchange,提问作者SingerOfTheFall
相关产品推荐
相关产品推荐

