edA-qa mort-ora-y
edA-qa mort-ora-y

Reputation: 31951

Why is this virtual call ambiguous?

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)

Upvotes: 5

Views: 248

Answers (2)

rodrigo
rodrigo

Reputation: 98526

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;
};

Upvotes: 6

user2448027
user2448027

Reputation: 1638

Class dual_applicator does not override virtual function apply.

Upvotes: 0

Related Questions