コンパイラは、あいまいさを診断することによって、ダイアモンドの問題が発生しているプログラムを見つけます。
解決策の 1 つは、あいまいさを取り除くことです。これは、明示的な名前修飾を使用してメンバーを参照するときに実行できます。
struct B {
int bar;
};
struct D1 : B {};
struct D2 : B {};
struct E : D1, D2 {};
int main() {
E e;
e.D1::bar = 1; // explicitly set D1::bar, not D2::bar.
}
または、次のようにベース サブオブジェクトにアクセスする場合: B *b = new E;
D1 または D2 のベース サブオブジェクトが必要かどうかはあいまいです。これらの中間型のいずれかへの明示的なキャストを使用すると、あいまいさが解決されます。
B *b = static_cast<D2*>(new E);
また、B* から E* へのダウンキャストは静的に行うことができないことに注意してください。コンパイラは、どの B が指されているかを認識していないため、ポインターを調整して E に戻す方法を静的に認識していません。ここで、dynamic_cast が必要になります。
E *e = new E;
B *b1 = static_cast<D1*>(e);
B *b2 = static_cast<D2*>(e);
assert(b1 != b2);
assert(dynamic_cast<E*>(b1) == dynamic_cast<E*>(b2));
assert(e == dynamic_cast<E*>(b1));
もう 1 つの解決策は、仮想継承の問題を回避して、同じ型の複数の基本サブオブジェクトを回避することです。
struct B {
virtual void foo() = 0;
virtual ~B() = default;
int bar;
};
struct D1 : virtual B {};
struct D2 : virtual B {};
struct E : D1, D2 {
virtual void foo() override {
bar = 1; // no ambiguity because there's only a single B base sub-object
}
};