消除C++中菱形问题访问顶级成员的歧义

Disambiguate the diamondproblem in c++ to access the top level member

首先,我想承认有 many questions with similar titles 和主题。我相当确定我的是独一无二的。

给定代码

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

我在尝试访问 Top::get() 的行上遇到错误(使用 gcc mingw-w64)

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

我收到一个错误。在这种情况下,如何向编译器发出信号以在特定继承路径上调用 Top::get

Bottom 是一个 derived class that is not using virtual inheritance,因此它有 2 个不同的 Top 实例 - 一个继承自 Mid1,另一个继承自 Mid2。因此,您必须明确告诉编译器您要从哪个 Top 实例调用 get(),例如:

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

你打算在Bottom里面放2份Top吗?如果是,则使用 Remy Lebeau 的答案。但是如果你想在 Bottom 中有一个 Top 的副本,那么使用虚拟继承:

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

在这种情况下,您的原始代码

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

将编译。