C++重载解析问题

发布于 2024-08-07 14:27:25 字数 1507 浏览 3 评论 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
    /* ... */
};

当我尝试对 G类型的对象调用 Bar() 时,使用 E* 时,我收到以下编译时错误:

错误:没有匹配的函数可用于调用“G::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、为什么编译器无法区分它们之间的区别?

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) void 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

谁许谁一生繁华 2024-08-14 14:27:25

只有最派生类中包含 Bar 重写的 Bar 版本才会被考虑进行重载解析,除非您添加 using 声明。如果你尝试的

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

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

话它应该会起作用。

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.

北风几吹夏 2024-08-14 14:27:25

从您的代码中:

  • G 扩展了 G 中的 D
  • 您在 Bar(E*) 上调用 <代码>G -> G 确实
    没有 Bar 方法,所以看看基础
  • 基类是 D
  • DBar(F*) 但没有 Bar(E*) --> ;
    struct E 与以下类型不同
    struct F 所以你会得到一个错误

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

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

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

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文