考虑此类:
class Base{
public:
void func(double a) = delete;
void func(int a) const {}
};
int main(){
Base base;
base.func(1);
return 0;
}
使用clang++编译时,会产生以下错误:
clang++ --std=c++11 test.cpp
test.cpp:22:7: error: call to member function 'func' is ambiguous
base.func(1);
使用g++会产生警告:
g++ -std=c++11 test.cpp
test.cpp: In function ‘int main()’:
test.cpp:22:13: warning: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second: base.func(1);
为什么此代码不明确?
最佳答案
非静态成员函数,类似于两个:
void func(double); // #1
void func(int) const; // #2
还接受一个implicit object parameter,它在重载解析([over.match]/p1)中被视为任何其他参数:将隐式对象参数合并到成员函数签名后,编译器会看到两个重载:
void func(Base&, double); // #1
void func(const Base&, int); // #2
并尝试根据调用选择最佳可行的功能:Base base;
base.func(1);
从base
(是Base
类型的非常量左值)到Base&
的转换具有完全匹配等级(直接引用绑定(bind)会产生Identity conversion)-请参见Table 13。从base
到const Base&
的转换也具有完全匹配等级,但是[over.ics.rank]/p3.2.6声明#1
具有更好的转换顺序:现在,对于第二个参数,从积分prvalue
1
到double
的转换是浮点积分转换([conv.fpint]),该转换被赋予了转换等级。另一方面,1
到int
是完全转换等级的身份转换。对于此参数,#2
被认为具有更好的转换顺序([over.ics.rank]/p3.2.2):要成功解决重载,就需要最多存在一个转换顺序不同的参数([over.match.best]):
在这里,ICS0(#1)优于ICS0(#2),但是ICS1(#2)却比ICS1(#1)好,因此编译器无法在两个重载之间进行选择并检测到歧义。
关于c++ - 为什么对成员函数的调用不明确?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42573771/