C ++重载解析问题

时间:2009-10-13 21:18:11

标签: c++ resolution overloading

我有以下结构:

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
    /* ... */
};

当我试图在G&lt; D&gt;类型的对象上调用Bar()时使用E *,我得到以下编译时错误:

  

错误:没有匹配函数来调用'G&lt; D&gt; :: Bar(E *&amp;)'

     

注意:候选人是:虚拟空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,为什么编译器不能区分它们呢?

2 个答案:

答案 0 :(得分:3)

从你的代码:

  • GD
  • 中延伸G<D>
  • 您致电Bar(E*)上的G - &gt; G 没有Bar方法,所以看看基础 类
  • 基类为D
  • DBar(F*)但没有Bar(E*) - &gt; struct E与...不同 struct F所以你收到错误

回答你的问题:E与F没有相关的类型,编译可以说明差异是你收到错误的原因。

我不确定你添加了哪个Bar虚拟,但是如果基类已经将Bar声明为虚拟,那么扩展它的所有类都已经具有Bar虚拟,所以如果将单词(virtual)添加到扩展类中则无关紧要。

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

答案 1 :(得分:3)

除非您添加Bar声明,否则只有包含覆盖Bar的派生程度最高的类中的using版本才会被视为重载解析。如果你试试

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

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

然后它应该工作。