4

ビジュアル スタジオ 2013。

与えられた:

class base_1
{
public:
    virtual void foo(int) = 0;
};

class base_2
{
public:
    virtual void foo(int, double) = 0;
};

class join_1_2 : public virtual base_1, public virtual base_2
{};

私はシンクを持っています:

void sink(join_1_2 &param)
{
    param.foo(42, 3.14);
}

しかし、次のコンパイラ エラーが発生します。

エラー C2385: 'foo' のあいまいなアクセス

ベース「base_1」の「foo」である可能性があります

またはベース「base_2」の「foo」である可能性があります

エラー C2660: 'base_1::foo': 関数は 2 つの引数を取りません

エラー C3861: 'foo': 識別子が見つかりません

私はこの問題を解決できることを知っています:

param.base_2::foo(42, 3.14);

しかし、想像できると思いますが、仮想継承は、私が一緒に暮らさなければならない罪の 1 つです。私はおそらくアダプタを書くつもりです。しかし、コンパイラが base_2 で foo を解決しようとするのを妨げている原因がわかりません。私の同僚は、これはコンパイラ エラーだと信じていますが、私はすぐにベンダーを責めるつもりはありません。

C++ 仕様では、基底クラス間でオーバーロードされた仮想メソッドを解決することについて何と言っていますか?

4

2 に答える 2

4

経験則では、異なるスコープの関数はオーバーロードされません。ここでは、foos が異なるスコープにあります。それらをオーバーロードしたい場合は、using-declarationでそれらを持ち込む必要があります:

class join_1_2 : public virtual base_1, public virtual base_2
{
public:
    using base_1::foo;
    using base_2::foo;
};
于 2015-12-16T23:18:09.477 に答える