文字“0”是 int 和 const string& 重载的有效候选者会导致调用不明确
literal `0` being a valid candidate for int and const string& overloads causes 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;
}
0
在 C++ 中是特殊的。空指针的值为 0
,因此 C++ 允许将 0
转换为指针类型。这意味着当你打电话给
a.f(0);
您可以使用值为 0
的 int
调用 void f(int i = 0) const
,或者您可以使用初始化为 null 的 char*
调用 void f(const std::string&)
.
通常 int
版本会更好,因为它是完全匹配但在这种情况下 int
版本是 const
,因此需要 "converting" a
到 const CppSyntaxA
,其中 std::string
版本不需要这样的转换,但需要先转换为 char*
,然后再转换为 std::string
。在这两种情况下,这被认为是足够的变化,可以被认为是相等的转换,因此是不明确的。使两个函数 const
或非 const
将解决问题,并且将选择 int
重载,因为它更好。
My question is why compiler only complained about it when the parameter was 0.
因为0不仅是整型字面量,而且还是空指针字面量。 1 不是空指针字面量,所以没有歧义。
歧义来自 std::string
的隐式转换构造函数,该构造函数接受指向字符的指针作为参数。
现在,从 int 到 int 的身份转换比从指针到字符串的转换更受欢迎,但是还有另一个涉及转换的参数:隐式对象参数。在一种情况下,转换是从 CppSyntaxA&
到 CppSyntaxA&
,而在另一种情况下,它是从 CppSyntaxA&
到 const CppSyntaxA&
。
因此,一个重载因一个参数而首选,另一个重载因另一个参数而首选,因此没有明确首选的重载。
The issue will be fixed by making both functions const.
如果两个重载都是 const
合格的,则隐式对象参数转换序列是相同的,因此其中一个重载是明确首选的。
我最近修复了一个错误。
在下面的代码中,一个重载函数是 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;
}
0
在 C++ 中是特殊的。空指针的值为 0
,因此 C++ 允许将 0
转换为指针类型。这意味着当你打电话给
a.f(0);
您可以使用值为 0
的 int
调用 void f(int i = 0) const
,或者您可以使用初始化为 null 的 char*
调用 void f(const std::string&)
.
通常 int
版本会更好,因为它是完全匹配但在这种情况下 int
版本是 const
,因此需要 "converting" a
到 const CppSyntaxA
,其中 std::string
版本不需要这样的转换,但需要先转换为 char*
,然后再转换为 std::string
。在这两种情况下,这被认为是足够的变化,可以被认为是相等的转换,因此是不明确的。使两个函数 const
或非 const
将解决问题,并且将选择 int
重载,因为它更好。
My question is why compiler only complained about it when the parameter was 0.
因为0不仅是整型字面量,而且还是空指针字面量。 1 不是空指针字面量,所以没有歧义。
歧义来自 std::string
的隐式转换构造函数,该构造函数接受指向字符的指针作为参数。
现在,从 int 到 int 的身份转换比从指针到字符串的转换更受欢迎,但是还有另一个涉及转换的参数:隐式对象参数。在一种情况下,转换是从 CppSyntaxA&
到 CppSyntaxA&
,而在另一种情况下,它是从 CppSyntaxA&
到 const CppSyntaxA&
。
因此,一个重载因一个参数而首选,另一个重载因另一个参数而首选,因此没有明确首选的重载。
The issue will be fixed by making both functions const.
如果两个重载都是 const
合格的,则隐式对象参数转换序列是相同的,因此其中一个重载是明确首选的。