Question

Can you tell me why the following code is giving me the following error - call of overloaded "C(int)" is ambiguous

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.

But that's not the case.

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

int main()
{
    C p(0);
}
Was it helpful?

Solution

This is discussed in "Effective C++" by Scott Meyer. 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. If you had a private C(int) member, the code you present would call C(float). 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.

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. 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.)

OTHER TIPS

0 is an int type. Because it can be implicitly cast to either a float or char equally, the call is ambiguous. Visibility is irrelevant for these purposes.

Either put 0.0, 0., or 0.0f, or get rid of the C(char) constructor entirely.

Edit: Relevant portion of the standard, section 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:

  • 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).
  • 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.

4) If a best viable function exists and is unique, overload resolution succeeds and produces it as the result. 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.

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);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top