你能告诉我为什么以下代码给我以下错误 - 调用重载“C(int)”是不明确的
我认为既然C(char x)是私有的,那么只有C(float)ctor从外部可见,并且应该通过将int转换为float来调用。
但事实并非如此。
class C
{
C(char x)
{
}
public:
C(float t)
{
}
};
int main()
{
C p(0);
}
答案 0 :(得分:18)
Scott Meyer在“Effective C ++”中对此进行了讨论。这个含糊不清的原因是他们希望确保仅仅改变成员的可见性不会改变其他地方已有代码的含义。
否则,假设您的C类位于某个标题中。如果你有一个私有的C(int)成员,你提出的代码将调用C(浮点数)。如果由于某种原因,C(int)成员被公开,那么旧代码会突然调用该成员,即使旧代码和它调用的函数都没有改变。
编辑:更多理由:
更糟糕的是,假设您有以下两个功能:
C A::foo()
{
return C(1.0);
}
C B::bar()
{
return C(1.0);
}
这两个函数可以调用不同的函数,具体取决于foo或bar是否被声明为C的朋友,或者A或B是否继承它。让相同的代码调用不同的函数是可怕的。
(这可能不如Scott Meyer的讨论那么好,但这就是主意。)
答案 1 :(得分:7)
0是int
类型。因为它可以隐式地转换为float或char,所以调用是不明确的。 可见性与这些目的无关。
放置0.0
,0.
或0.0f
,或完全摆脱C(char)
构造函数。
编辑:标准的相关部分,第13.3节:
3)[...]但是,一旦确定了候选函数和参数列表,在所有情况下最佳函数的选择都是相同的:
- 首先,选择候选函数的子集 - 具有适当数量的参数并满足某些其他条件的函数 - 以形成一组可行的函数(13.3.2)。
- 然后根据将每个参数与每个可行函数的相应参数匹配所需的隐式转换序列(13.3.3.1)来选择最佳可行函数。
4)如果存在最佳可行功能并且是唯一的,则重载决策成功并将其作为结果产生。否则重载解析失败并且调用格式错误。当重载解析成功,并且在使用它的上下文中无法访问最佳可行功能(第11节)时,程序就会形成错误。
请注意,可见性不是选择过程的一部分。
答案 2 :(得分:-1)
我不这么认为:
C p(0);
正在转换为:
C(float t)
你可能需要这样做:
C p(0.0f);