简体   繁体   English

C ++ - 构造函数重载 - 私有和公共

[英]C++ - Constructor overloading - private and public

Can you tell me why the following code is giving me the following error - call of overloaded "C(int)" is ambiguous 你能告诉我为什么下面的代码给我以下错误 - 调用重载“C(int)”是不明确的

I would think that since C(char x) is private, only the C(float) ctor is visible from outside and that should be called by converting int to float. 我认为既然C(char x)是私有的,只有C(float)ctor从外部可见,应该通过将int转换为float来调用。

But that's not the case. 但事实并非如此。

class C
{
    C(char  x)
    {
    }
public:
    C(float t)
    {
    }
};

int main()
{
    C p(0);
}

This is discussed in "Effective C++" by Scott Meyer. 这在Scott Meyer的“Effective C ++”中讨论过。 The reason this is ambiguous is that they wanted to ensure that merely changing the visibility of a member wouldn't change the meaning of already-existing code elsewhere. 这个含糊不清的原因是他们希望确保仅仅改变成员的可见性不会改变其他地方已有代码的含义。

Otherwise, suppose your C class was in a header somewhere. 否则,假设您的C类位于某个标题中。 If you had a private C(int) member, the code you present would call C(float). 如果你有一个私有的C(int)成员,你提出的代码将调用C(浮点数)。 If, for some reason, the C(int) member was made public, the old code would suddenly call that member, even though neither the old code, nor the function it called had changed . 如果由于某种原因,C(int)成员被公开,旧代码会突然调用该成员,即使旧代码和它调用的函数都没有改变

EDIT: More reasons: 编辑:更多原因:

Even worse, suppose you had the following 2 functions: 更糟糕的是,假设您有以下两个功能:

C A::foo() 
{
    return C(1.0);
}

C B::bar() 
{
    return C(1.0);
}

These two functions could call different functions depending on whether either foo or bar was declared as a friend of C, or whether A or B inherits from it. 这两个函数可以调用不同的函数,具体取决于foo或bar是否被声明为C的朋友,或者A或B是否继承它。 Having identical code call different functions is scary. 使用相同的代码调用不同的函数是可怕的。

(That's probably not as well put as Scott Meyer's discussion, but that's the idea.) (这可能不如斯科特迈耶的讨论那么好,但这就是主意。)

0 is an int type. 0是int类型。 Because it can be implicitly cast to either a float or char equally, the call is ambiguous. 因为它可以隐式地转换为float或char,所以调用是不明确的。 Visibility is irrelevant for these purposes. 可见性与这些目的无关。

Either put 0.0 , 0. , or 0.0f , or get rid of the C(char) constructor entirely. 要么把0.00. ,或0.0f ,或摆脱了C(char)完全构造。

Edit: Relevant portion of the standard, section 13.3: 编辑:标准的相关部分,第13.3节:

3) [...] But, once the candidate functions and argument lists have been identified, the selection of the best function is the same in all cases: 3)[...]但是,一旦确定了候选函数和参数列表,最佳函数的选择在所有情况下都是相同的:

  • First, a subset of the candidate functions—those that have the proper number of arguments and meet certain other conditions—is selected to form a set of viable functions (13.3.2). 首先,选择候选函数的子集 - 具有适当数量的参数并满足某些其他条件的候选函数 - 以形成一组可行的函数(13.3.2)。
  • Then the best viable function is selected based on the implicit conversion sequences (13.3.3.1) needed to match each argument to the corresponding parameter of each viable function. 然后,基于将每个参数与每个可行函数的相应参数匹配所需的隐式转换序列(13.3.3.1)来选择最佳可行函数。

4) If a best viable function exists and is unique, overload resolution succeeds and produces it as the result. 4)如果存在最佳可行功能并且是唯一的,则重载决策成功并将其作为结果产生。 Otherwise overload resolution fails and the invocation is ill-formed. 否则重载解析失败并且调用格式错误。 When overload resolution succeeds, and the best viable function is not accessible (clause 11) in the context in which it is used, the program is ill-formed. 当重载决策成功,并且在使用它的上下文中无法访问最佳可行功能(第11节)时,程序是不正确的。

Note that visibility is not part of the selection process. 请注意,可见性不是选择过程的一部分。

I don't think that: 我不这么认为:

C p(0);

is being converted to: 正在被转换为:

C(float t)

you probably need to do: 你可能需要这样做:

C p(0.0f);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM