ダイヤモンド問題を解決するために using 宣言が機能しないのはなぜですか? 質問する

ダイヤモンド問題を解決するために using 宣言が機能しないのはなぜですか? 質問する

次のコードを検討してください。

struct A
{
    void f()
    {
    }
};

struct B1 : A
{
};

struct B2 : A
{
};

struct C : B1, B2
{
    void f() // works
    {
        B1::f();
    }
    //using B1::f; // does not work
    //using B1::A::f; // does not work as well
};

int main()
{
    C c;
    c.f();

    return 0;
}

ダイヤモンド問題を解決する方法に関する標準的な回答 (「仮想継承を使用する」) をコピーして貼り付けないでください。ここで私が尋ねているのは、この場合に using 宣言が機能しない理由です。正確なコンパイラ エラーは次のとおりです。

In function 'int main()':
prog.cpp:31:6: error: 'A' is an ambiguous base of 'C'
  c.f();

次の例から、using 宣言が機能するはずだという印象を受けました。

struct A
{
    void f()
    {
    }
};

struct B
{
    void f()
    {
    }
};

struct C : A, B
{
    using A::f;
};

int main()
{
    C c;
    c.f(); // will call A::f

    return 0;
}

ベストアンサー1

標準的な引用文は他の人が見つけることもできますが、私は概念的に説明します。

それは機能しない。使用宣言 名前の検索にのみ影響します。

あなたの使用宣言通常は失敗する名前検索を成功させる。つまり、コンパイラに関数はどこにありますかfしかし、それは語られていないどのAサブオブジェクトfが作用するかつまり、が呼び出されたthisときに暗黙のパラメータとして渡されるものを指定しますf

のサブオブジェクトA::fが2つあるにもかかわらず、関数は1つしか存在せず、暗黙的に型の引数を取ります。オブジェクトでそれを呼び出すには、を暗黙的に に変換する必要があります。これは常に曖昧であり、いかなる影響も受けません。ACthisA*CC*A*使用宣言

(データ メンバーを 内に配置すると、より意味をなしますA。 すると、には、Cこのようなデータ メンバーがそれぞれ 2 つずつ含まれることになります。が呼び出され、データ メンバーにアクセスする場合、から継承されたサブオブジェクトf内のデータ メンバーにアクセスするのでしょうか、それともから継承されたサブオブジェクト内のデータ メンバーにアクセスするのでしょうか。)AB1AB2

おすすめ記事