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*)

如果我重命名 (virtual) 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

从您的代码:

  • G延伸DG<D>
  • 您调用->没有方法Bar(E*),因此请查看基类GGBar
  • 基类是D
  • Dhas Bar(F*)but no Bar(E*)--> struct Eis different type from struct F所以你得到一个错误

回答您的问题: E 与 F 类型无关,编译可以区分这就是您收到错误的原因。

我不确定您添加了哪个 Bar 虚拟,但是如果基类已经将 Bar 声明为虚拟,那么所有扩展它的类都已经具有 Bar 虚拟,因此是否将单词 (virtual) 添加到扩展类中并不重要。

如果您展示了如何实例化对象以及如何在其上调用 Bar(F*),将会有所帮助。运行时决策取决于您调用方法的方式和传递的参数。

于 2009-10-13T21:33:33.110 回答
3

除非您添加声明,否则只会考虑重载决议Bar中包含重写的最派生类中的版本。如果你试试Barusing

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

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

那么它应该可以工作。

于 2009-10-13T21:58:20.317 回答