I'm confused by this situation and googling didn't give me the answer. Basically I have the following simple code that doesn't compile:
#include <iostream>
class A
{
public:
int a(int c = 0) { return 1; }
static int a() { return 2; }
};
int main()
{
std::cout << A::a() << std::endl;
return 0;
}
In compiling this, GCC 4.2 says the call to A::a()
in main()
is ambiguous with both versions of a()
valid candidates. Apple's LLVM compiler 3.0 compiles with no error.
Why is gcc confused about which function I want to call? I thought it was obvious that by qualifying a()
with A::
I'm asking for the static
version of the function. Naturally this code still doesn't compile if I remove the static
function a()
, because A::a()
is not valid syntax for calling the non-static
a()
.
Thanks for any comment!
There are two ways to resolve this ambiguity: Typecast char to float. Remove either one of the ambiguity generating functions float or double and add overloaded function with an int type parameter.
When the compiler is unable to decide which function it should invoke first among the overloaded functions, this situation is known as function overloading ambiguity. The compiler does not run the program if it shows ambiguity error.
You cannot override one virtual function with two or more ambiguous virtual functions. This can happen in a derived class that inherits from two nonvirtual bases that are derived from a virtual base class.
How can a call to an overloaded function be ambiguous ? EXPLANATION : The call to an overloaded function can be ambiguous if the two or more functions have the same name and same function signature.
The reason for this is because C++ specifies that this is ambiguous. Overload resolution specifies that for A::a
, since this
is not in scope, the argument list in that call is augmented by a contrived A object argument, instead of *this
. Overload resolution does not exclude non-static member functions, but instead
If the argument list is augmented by a contrived object and overload resolution selects one of the non-static member functions of T, the call is ill-formed.
This has recently been subject of extensive discussion both in the committee in context of core issue 1005. See core issue 364 which considered changing this rule but didn't do so.
The reason is name resolution happens before anything else the compiler does, like figuring out which overloaded function to use.
Qualifying the function with A::
simply tells the compiler to "look inside of A
to find the name a
". It doesn't actually help resolve which function you are referring to.
EDIT
And so when you type A::a()
, first the compiler thinks "look in A
for a member function or member who can use operator()
".
Then the compiler thinks, "Ok, two possibilities here, which one is being referred to? a()
or a(int c = 0)
with a default c=0
. Not sure.
If you removed the static keyword and called the functions like obj.a()
, there would still be an ambiguity.
WRT LLVM's parser
I would say that it does some extra work for you, which is not required by the standard, which would be to assume A::a()
is static.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With