C++重载函数与多转换运算符歧义问题 不同编译器表现不一致
struct S { operator double() { return 3; } operator long long int() { return 4; } }; void f( double ) {} void f( float ) {} int main() { S s; f( s ); }
你的判断中「operator long long int() 到 float 的转换不属于类型提升」的表述是正确的,但该点不足以支撑「MSVC处理正确」的结论,GCC、Clang的歧义判定才是符合C++标准的行为,MSVC的处理属于不符合标准的实现扩展。
判定依据
C++重载决议中,对用户自定义转换序列的优先级比较遵循以下规则:
- 每个用户自定义转换序列的构成为:前置标准转换 → 用户自定义转换(转换运算符/转换构造函数) → 后置标准转换
- 只有当两个转换序列使用同一个用户自定义转换函数时,才会通过比较前后置标准转换的等级来判定哪个序列更优
- 如果两个转换序列使用了不同的用户自定义转换函数,那么二者不存在优先级高低之分,会直接判定为歧义
对应到示例场景:
- 匹配
f(double)的转换序列:调用operator double(),后置无额外转换,属于精确匹配 - 匹配
f(float)的转换序列:调用operator long long int(),后置为long long int转float的整数-浮点标准转换
两个序列使用了完全不同的转换运算符,因此哪怕后者的后置转换等级更低,也不会因此判定前者更优,本次调用天然属于歧义场景。
你提到的类型提升场景属于转换运算符唯一的情况,此时两个重载的转换序列使用同一个用户自定义转换函数,才会进入后置标准转换的等级比较,所有编译器表现一致,和本次场景的核心逻辑不同。
内容的提问来源于stack exchange,提问作者Fedor
相关产品推荐
相关产品推荐

