为什么这个呼吁会员函数模棱两可
Why is this call to member function ambiguous?
考虑此类:
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
还接受一个隐式对象参数,该参数在过载分辨率([Over.Match]/p1)中被视为任何其他参数:
超载分辨率是一种机制,可以选择给定表达式列表的最佳函数,这些函数是呼叫的参数和一组候选函数,可以根据呼叫的上下文调用。最佳函数的选择标准是参数数量,参数匹配候选函数的参数类型列表的很好,对象(对于非静态成员函数)对象匹配隐式对象参数以及候选功能的某些其他属性。
将隐式对象参数纳入成员函数签名后,编译器会看到两个过载:
void func(Base&, double); // #1
void func(const Base&, int); // #2
并尝试根据呼叫选择最佳的可行函数:
Base base;
base.func(1);
从base
(Base
类型的非const lvalue)转换为Base&
的转换具有 ext excrack Match 等级(直接参考绑定产生身份转换) - - 请参见表13。但是,从base
到const Base&
的转换也是 exceck ackect匹配等级,但是,[over.ics.rank]/p3.2.6声明#1
具有更好的转换顺序:blockquote>
- s1和s2是参考绑定([dcl.init.ref]),并且参考引用的类型是相同的类型,除了顶级CV-Qualifiers,以及由该类型的类型以及由该类型的类型,该类型由该类型由该类型由此由此引用。S2引用比S1初始化的参考文献的类型更为CV质量。[示例:
int f(const int &);
int f(int &);
int g(const int &);
int g(int);
int i;
int j = f(i); // calls f(int &)
int k = g(i); // ambiguous
现在,对于第二个参数,从积分prvalue 1
到 double
的转换为 floating-integral conversion ([cons.fpint]),该转换给了转换秩。另一方面, 1
到 int
是身份转换,它是的等级。对于此参数,#2
被认为具有更好的转换序列([over.ics.rank]/3.2.2):
- S1的等级大于S2的等级,或S1和S2的等级相同,并且可以通过以下段落中的规则来区分,或者,如果不是这样,[...]
超载分辨率要成功,要求最多存在一个参数,转换序列有所不同([over.match.best]):
鉴于这些定义,如果对于所有参数i,ICS i (f1),可行函数f1被定义为比另一个可行函数f2更好的函数。sub> i (f2),然后
- 对于某个参数J,ICS
J (F1)比ICS J (F2)更好的转换序列,或者,如果不是这样,[...]
在这里,ICS 0 (#1)优于ICS
函数被超载时,超载分辨率首先进行。如果已删除的函数是最好的匹配并选择了程序。
因此,您的程序将产生与以下错误相同的错误,因为从int到double有隐式转换,并且编译器不知道您打算调用什么函数:
class Base{
public:
void func(double a) {}
void func(int a) const {}
};
它是因为func(int)
中的const
修饰符。base
实例不是const。如果实例不是const,则C 编译器似乎首先找到non-const
方法。然后,编译器发现该方法已被删除。因此编译器发出警告。
尝试删除const
修饰符,或将const
修饰符移至func(double)
将摆脱警告。
看来此警告与隐式转换无关。即使您通过func((int)(1))
调用func
也不好。
- 模棱两可的调用 - 模板化函数
- 为什么此C++代码中的构造函数模棱两可以及如何修复它
- 如果类仅通过要求启用单个成员函数,仍然可以模棱两可地超载
- 将一组类转换为类模板并避免构造函数模棱两可
- 使用Kinect,错误C2668:对过载函数的模棱两可
- 为什么这个呼吁会员函数模棱两可
- C 从同一基本模板类覆盖功能,具有多个继承模棱两可的函数调用
- 给定一个已经定义的模板函数,是否可以用另一个模板函数重载它而不会模棱两可
- C 成员函数是模棱两可的
- C 汇编错误:对构造函数的引用是模棱两可的
- 看似模棱两可的模板函数重载
- 重载函数的调用 - 以继承的类作为参数 - 是模棱两可的
- 为什么对函数的调用"sample_mean"模棱两可的?
- 没有函数重写的多重继承.为什么模棱两可
- 模棱两可的重载函数 - 如何以及为什么
- 为什么我的 T& 和 T&& copy 构造函数模棱两可?
- c++中模棱两可的函数重载
- 对重载函数的模棱两可的调用,即使一个更专业
- 重载函数会产生模棱两可的错误
- 对函数的调用在C++中是模棱两可的.候选函数是原型和函数本身