In the below code I can't figure out why the call to "apply" is reported as ambiguous. There is only one acceptable match for the provided parameter (A_applicator::apply
). Note I'd much appreciate references to the standard which would help me determine the resolution flow that causes this ambiguity.
struct A { };
struct B { };
struct A_D : public A { };
struct A_applicator {
virtual void apply( A ) { }
};
struct B_applicator {
virtual void apply( B ) { }
};
struct dual_applicator : public B_applicator, public A_applicator {
};
int main() {
dual_applicator app;
A_D d;
app.apply(d);
}
(Online Demo)
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.
Whenever you see a compiler error that says something is ambiguous it normally means that you have opened some namespaces (ie using namespace std;) and other namespaces and cout is defined in both namespaces. This means it is ambiguous, the compiler does not know which definition you mean.
Ambiguity in inheritance can be defined as when one class is derived for two or more base classes then there are chances that the base classes have functions with the same name. So it will confuse derived class to choose from similar name functions. To solve this ambiguity scope resolution operator is used “::”.
You seem to think that it should not be ambiguity because one of the functions cannot be called, based on the type of the arguments. But that's not how C++ name resolution works.
This is how it works, more or less: the name of the function is resolved into an overload set. And then the argument list is used to choose between the functions in that set.
Your problem is that the first step cannot be done, because the name apply
how it is used, can refer to two different overload sets, and the compiler doesn't know which one to use. It didn't even begin to look at the parameters!
The solutions are easy:
A) Say which function you want:
app.A_applicator::apply(d);
B) Use using
to build a unified overload set of member functions, so the expected resolution using arguments is used.
struct dual_applicator : public B_applicator, public A_applicator {
using A_applicator::apply;
using B_applicator::apply;
};
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