繁体   English   中英

多重继承导致虚假模糊虚拟 function 过载

[英]Multiple inheritence leads to spurious ambiguous virtual function overload

在此示例中,类FooBar是从库中提供的。 我的 class Baz继承自两者。

struct Foo
{
    void do_stuff (int, int);
};

struct Bar
{
    virtual void do_stuff (float) = 0;
};

struct Baz : public Foo, public Bar
{
    void func ()
    {
        do_stuff (1.1f); // ERROR HERE
    }
};

struct BazImpl : public Baz
{
    void do_stuff (float) override {};
};

int main ()
{
    BazImpl () .func ();
}

我得到reference to 'do_stuff' is ambiguous ,这对我来说似乎是虚假的,因为两个 function 签名完全不同。 如果do_stuff是非虚拟的,我可以调用Bar::do_stuff来消除歧义,但这样做会破坏多态性并导致 linker 错误。

我可以在不重命名的情况下让func调用虚拟do_stuff吗?

你可以这样做:

struct Baz : public Foo, public Bar
{
    using Bar::do_stuff;
    using Foo::do_stuff;
    //...
}

用最新的wandbox gcc 测试,编译良好。 我认为 function 重载的情况相同,一旦重载一个,你就不能使用基本 class 实现而不using .

实际上这与虚函数无关。 以下示例具有相同的错误GCC 9.2.0 error: reference to 'do_stuff' is ambiguous

struct Foo
{
    void do_stuff (int, int){}
};

struct Bar
{
    void do_stuff (float) {}
};

struct Baz : public Foo, public Bar
{
    void func ()
    {
        do_stuff (1.1f); // ERROR HERE
    }
};

可能的相关问题

名称查找和重载解析是不同的。 该名称必须首先在 scope 中找到,即我们必须找到一个X以便将名称do_stuff解析为X::do_stuff与名称的使用无关——然后重载解析在X::do_stuff的不同声明之间进行选择X::do_stuff

该过程不是识别所有可见A::do_stuffB::do_stuff等情况,然后在它们的联合中执行重载解决方案。 相反,必须为名称标识单个 scope。

在这段代码中:

struct Baz : public Foo, public Bar
{
    void func ()
    {
        do_stuff (1.1f); // ERROR HERE
    }
};

Baz不包含名称do_stuff ,因此可以查找基类。 但名称出现在两个不同的基数中,因此名称查找无法识别 scope。 我们从来没有达到过重载决议。

另一个答案中的建议修复有效,因为它将名称do_stuff引入了Baz的 scope ,并且还为该名称引入了 2 个重载。 因此,名称查找确定do_stuff表示Baz::do_stuff ,然后重载决议从称为Baz::do_stuff的两个函数中进行选择。


顺便说一句,阴影是名称查找的另一个结果(本身不是规则)。 名称查找选择内部 scope,因此外部 scope 中的任何内容都不匹配。

依赖于参数的查找在起作用时,会出现更复杂的因素。 简而言之,对于使用 class 类型的 arguments 的 function 调用(我的回答中描述的基本版本),名称查找会进行多次,然后再针对每个参数类型。 然后找到的范围的联合进入重载集。 但这不适用于您的示例,因为您的 function 只有内置类型的参数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM