0

私は次の構造を持っています:

struct  A
{
    A();
    virtual ~A();
    
    virtual void    Foo() =0;
};

struct  E;
struct  F;

struct  B:  public A
{
    B();
    virtual ~B();
    
    virtual void    Bar(E*) =0;
    virtual void    Bar(F*) =0;
};

struct  C:  public B
{
    C();
    virtual ~C();
    
    void    Bar(E*);
};

struct  D:  public C
{
    D();
    virtual ~D();
    
    void    Foo();
    void    Bar(F*);
};

struct  E:  public A
{
    E();
    virtual ~E();
    
    void    Foo();
    /* ... */
};

struct  F:  public A
{
    F();
    virtual ~F();
    
    void    Foo();
    /* ... */
};

template <class _Base>
struct  G:  public _Base
{
    G(const _Base &b)
    :   _Base(b)
    {}

    virtual ~G()
    {}
    
    using _Base::Bar; // doesn't help
    /* ... */
};

E* を使用して G<D> 型のオブジェクトで Bar() を呼び出そうとすると、次のコンパイル時エラーが発生します。

エラー: 'G<D>::Bar(E*&)' の呼び出しに一致する関数がありません

注: 候補は: virtual void D::Bar(F*)

(仮想) void Bar(F*) の宣言の名前を変更すると、コードは正常にコンパイルされ、期待どおりに動作します。

使用法:

typedef std::list<E*> EList;
typedef std::list<F*> FList;
EList es;
FList fs;

G<D> player(D());

es.push_back(new E); // times many
fs.push_back(new F); // times many

for(EList::iterator i0(es.begin()), i1(es.end()); i0 != i1; ++i0)
{
  player.Bar(*i0);
}

for(FList::iterator i0(fs.begin()), i1(fs.end()); i0 != i1; ++i0)
{
  player.Bar(*i0);
}

1、異なる引数を取るメンバー関数の複数のオーバーロードの何が問題になっていますか?

2、なぜコンパイラはそれらの違いを見分けられないのですか?

4

2 に答える 2

3

Barのオーバーライドを含む最も派生したクラスののバージョンのみが、宣言Barを追加しない限り、オーバーロードの解決と見なされます。using試してみると

struct  D:      public C
{
    D();
    virtual ~D();

    void        Foo();
    void        Bar(F*);
    using C::Bar;
};

それならうまくいくはずです。

于 2009-10-13T21:58:20.317 に答える
3

あなたのコードから:

  • GDに広がるG<D>
  • Bar(E*)あなたが呼び出すG- >メソッドGがないBarので、基本クラスを調べます
  • ベースクラスはD
  • Dhas Bar(F*)but no Bar(E*)--> struct Eis different type from で struct Fあるため、エラーが発生します

あなたの質問に答えるには: E は F に関連する型ではなく、コンパイルは違いを伝えることができるため、エラーが発生します。

どのバーを仮想に追加するかはわかりませんが、基本クラスがすでにバーを仮想として宣言している場合、それを拡張するすべてのクラスはすでに仮想バーを持っているため、拡張クラスに単語 (仮想) を追加しても問題ありません。

オブジェクトをインスタンス化する方法と、その上で Bar(F*) を呼び出す方法を示していただければ助かります。メソッドの呼び出し方法と渡すパラメーターに依存する実行時の決定があります。

于 2009-10-13T21:33:33.110 に答える