开发者

C++ overload resolution problem

开发者 https://www.devze.com 2022-12-08 16:38 出处:网络
I\'ve got the following structure: structA { A(); virtual ~A(); virtual voidFoo() =0; }; structE; structF; structB:public A

I've got the following structure:

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

When I'm trying to call Bar() on an object of type G<D> with a E*, I get the following compile-time error:

error: no matching function for call to 'G<D>::Bar(E*&)'

note: candidates are: virtual void D::Bar(F*)

If I rename the declarations of (virtual) voi开发者_如何转开发d Bar(F*), the code compiles fine and works as expected.

Usage:

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, What's wrong with multiple overloads of member functions taking different arguments?

2, Why can't the compiler tell the difference between them?


Only the versions of Bar in the most-derived class containing an override of Bar will be considered for overload resolution unless you add in using declarations. If you try

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

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

then it should work.


From your code:

  • G extends D in G<D>
  • you call on Bar(E*) on G -> G does not have Bar method so look into base class
  • base class is D
  • D has Bar(F*) but no Bar(E*) --> struct E is different type from struct F so you get an error

To answer your question: E is not related type to F and compile can tell the difference that's why you're getting an error.

I'm not sure which Bar you add virtual but if the base class already declares Bar as virtual all the classes that extends it already have Bar virtual so it does not matter if you add the word (virtual) into extended classes.

It would help if you showed how you instantiate your object and how you call Bar(F*) on it. There are runtime decisions that depends on how you call method and what parameters you passing.

0

精彩评论

暂无评论...
验证码 换一张
取 消