[英]Multiple inheritence leads to spurious ambiguous virtual function overload
在此示例中,类Foo
和Bar
是从库中提供的。 我的 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_stuff
、 B::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.