2

First I would like to acknowledge that there are many questions with similar titles and subject matter. I'm fairly certain mine is unique from them.

Given the code

struct Top {
    int get() {
        return 0;
    }
};

struct Mid1 : Top {
    int get() {
        return 1;
    }
};

struct Mid2 : Top {
    int get() {
        return 2;
    }
};

struct Bottom : Mid1, Mid2 {

};

int main(int argc, char ** argv) {
    Bottom b;
    std::cout << b.Mid1::get();
    std::cout << b.Mid2::get()
    std::cout << b.Top::get();
}

I get an error on the line trying to access Top::get() with the error (using gcc mingw-w64)

 error: 'Top' is an ambiguous base of 'Bottom'
 std::cout << b.Top::get();

I get an error. How would one signal to the compiler to call Top::geton a specific inheritance path in this case?

rtpax
  • 1,687
  • 1
  • 18
  • 32

2 Answers2

3

Bottom is a derived class that is not using virtual inheritance, so it has 2 distinct instances of Top - one inherited from Mid1, and another from Mid2. As such, you must explicitly tell the compiler which instance of Top you want to call get() from, eg:

std::cout << b.Mid1::get(); // OK
std::cout << b.Mid2::get(); // OK
std::cout << b.Top::get(); // ERROR!
std::cout << b.Mid1::Top::get(); // ERROR!
std::cout << b.Mid2::Top::get(); // ERROR!
std::cout << static_cast<Mid1&>(b).Top::get(); // OK
std::cout << static_cast<Mid2&>(b).Top::get(); // OK

Live Demo

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • This does exactly what I was looking for in an answer. A bit ugly, but I wouldn't really expect much else. – rtpax Aug 23 '18 at 20:18
0

Is your intention to have 2 copies of Top inside Bottom? If it is, then use the answer from Remy Lebeau. But if you instead want to have a single copy of Top inside Bottom, then use virtual inheritance:

struct Mid1 : virtual Top {...}
struct Mid2 : virtual Top {...}

In this case, your original code

std::cout << b.Top::get();

will compile.

Eugene
  • 6,194
  • 1
  • 20
  • 31