Con*_* Ma 44 c++ overloading ambiguous-call
我最近修复了一个错误。
在以下代码中,一个重载函数是const,而另一个则不是。通过将两个函数都设为const可以解决此问题。
我的问题是为什么编译器只在参数为0时才抱怨它。
#include <iostream>
#include <string>
class CppSyntaxA
{
public:
void f(int i = 0) const { i++; }
void f(const std::string&){}
};
int main()
{
CppSyntaxA a;
a.f(1); // OK
//a.f(0); //error C2666: 'CppSyntaxA::f': 2 overloads have similar conversions
return 0;
}
Run Code Online (Sandbox Code Playgroud)
Nat*_*ica 56
0在C ++中是特殊的。空指针的值为,0因此C ++允许将转换为0指针类型。那意味着当你打电话
a.f(0);
Run Code Online (Sandbox Code Playgroud)
你可以调用void f(int i = 0) const与int同值0,或者你可以调用void f(const std::string&)一个char*初始化为空。
通常情况下,int版本会更好,因为它是完全匹配的,但在这种情况下,int版本是const,因此它需要“转换” a为const CppSyntaxA,其中std::string版本不需要进行此类转换,但需要先转换为char*,然后转换为std::string。在两种情况下,这都足以视为相等的转换,因此模棱两可。同时启用const或禁用这两个功能const将解决此问题,并int选择过载,因为这样做更好。
eer*_*ika 11
我的问题是为什么编译器只在参数为0时才抱怨它。
因为0不仅是整数文字,而且还是空指针文字。1不是空指针文字,因此没有歧义。
The ambiguity arises from the implicit converting constructor of std::string that accepts a pointer to a character as an argument.
Now, the identity conversion from int to int would otherwise be preferred to the conversion from pointer to string, but there is another argument that involves a conversion: The implicit object argument. In one case, the conversion is from CppSyntaxA& to CppSyntaxA& while in other case it is CppSyntaxA& to const CppSyntaxA&.
So, one overload is preferred because of one argument, and the other overload is preferred because of another argument and thus there is no unambiguously preferred overload.
The issue will be fixed by making both functions const.
如果两个重载都const合格,则隐式对象参数转换序列相同,因此,无疑要选择其中一个重载。