Holt
Holt

Reputation: 37626

Disambiguate base class when calling non-virtual member

Consider the following inheritance hierarchy:

struct Top {
    void foo();
    virtual void bar() = 0;
};

struct Mid1: Top {
    virtual void bar() override { }
};
struct Bot1: Mid1 { };

struct Mid3: Top {
    virtual void bar() override { }
};

struct Bot3: Mid3, private Bot1 {
    using Mid3::bar;
    using Mid3::foo;
};

And the following snippet:

Bot3 b;
b.foo(); // does not compile
b.bar(); // compile

The error is:

test.cpp:28:5: error: ambiguous conversion from derived class 'Bot3' to base class 'Top':

struct Bot3 -> struct Mid3 -> struct Top

struct Bot3 -> struct Bot1 -> struct Mid1 -> struct Top

b.foo();
^

Is there a simple way to tell the compiler to use the first "conversion" sequence? using Mid3::foo; have no effects here (standard behaviour).

I know I can define foo() in Bot3 and simply call Mid3::foo(), but I would like to avoid this if possible.

Upvotes: 1

Views: 259

Answers (2)

v1bri
v1bri

Reputation: 1428

In this situation you can give the compiler some help by letting it know which branch of the inheritance tree it should descend to call your base class method.

int main(int argc, char* argv[]) {
    Bot3 b;
    static_cast<Mid3*>(&b)->foo();
    return 0;
}

Upvotes: 1

Nicol Bolas
Nicol Bolas

Reputation: 473537

Ambiguous situations are ambiguous. C++ doesn't allow you to have the "first" take priority; you must explicitly disambiguate the call each time.

Or just make a function in the derived class which forwards to the right base class function.

Upvotes: 1

Related Questions