C++ 具有多个函数和多个转换运算符的重载解析
考虑简单的代码:C++ 具有多个函数和多个转换运算符的重载解析,c++,overloading,language-lawyer,overload-resolution,conversion-operator,C++,Overloading,Language Lawyer,Overload Resolution,Conversion Operator,考虑简单的代码: #include<iostream> struct A { operator double(){ std::cout<<"Conversion function double chosen."<<std::endl; return 1.1; } operator char(){ std::cout<<"Conversion function char cho
#include<iostream>
struct A {
operator double(){
std::cout<<"Conversion function double chosen."<<std::endl;
return 1.1;
}
operator char(){
std::cout<<"Conversion function char chosen."<<std::endl;
return 'a';
}
} a;
void foo(int){}
void foo (char){}
int main() {
foo(a);
}
现在应该选择foo(double)
,但似乎只有VC++对代码感到满意,而clang和gcc对上述代码不满意
main.cpp:11:10: error: call of overloaded 'foo(A&)' is ambiguous
foo(a);
^
main.cpp:8:6: note: candidate: void foo(int)
void foo(int){}
^
main.cpp:9:6: note: candidate: void foo(double)
void foo (double){} //parameter changed from char to double
^
有人能解释为什么上面的代码失败吗?还是虫子
还有一个问题:gcc和clang是否共享重载解决方案的代码?
A->char
是A->char
A->int
是A->char->int
(因为char
到int
是一种提升,因此比到int
的转换更有效)
A->double
是A->double
两个用户定义的转换序列只有在涉及相同的用户定义转换函数时才具有可比性。因此,A->char
是比A->int
更好的转换顺序,因此第一种情况是明确的。A->int
和A->double
都不比另一种好,因此第二种情况是不明确的;DR
:区别在于第一种情况与第二种情况相反,用户定义的转换序列(A->char
,A->int
)调用相同的转换函数(operator char
)。这使我们能够通过[over.ics.rank]/(3.3)打破僵局
通过(比较其返回类型的转换序列)选择特定函数的最佳转换运算符 因此,
foo(int)
更好的转换函数是运算符char
,然后升级到int
,而不是运算符double
然后进行浮点转换
现在考虑第二次过载的两种变体:
foo(char)
的最佳IC也是通过运算符char
(标识优于浮点转换)。因此适用于:
如果用户定义的转换序列U1
包含相同的用户定义转换函数,则它们比另一个用户定义的转换序列U2
更好在任何一种情况下,U1
的第二标准转换序列都优于U2
的第二标准转换序列
因此,对F2
的整体转换被认为是更好的,并被选中foo(double)
的最佳ICS是通过运算符double
。我们最终得到两个使用不同转换函数的转换序列;没有什么真正适用的,我们只是得到了一个模糊性1:定义“不快乐”。2:如果删除
foo(int)
,会发生什么?@Amit unful表示代码被拒绝,至于删除函数foo(int)
,这不是问题的一部分,您可以自己试试。@AngelusMortis:VC++选择哪个函数?
main.cpp:11:10: error: call of overloaded 'foo(A&)' is ambiguous
foo(a);
^
main.cpp:8:6: note: candidate: void foo(int)
void foo(int){}
^
main.cpp:9:6: note: candidate: void foo(double)
void foo (double){} //parameter changed from char to double
^