多重继承导致虚假的模糊虚拟函数过载
Multiple inheritence leads to spurious ambiguous virtual function overload
在本例中,类Foo
和Bar
是从库中提供的。我的类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
,这对我来说似乎是伪造的,因为两个函数签名完全不同。如果do_stuff
是非虚拟的,我可以调用Bar::do_stuff
来消除它的歧义,但这样做会破坏多态性并导致链接器错误。
我可以让func
调用虚拟do_stuff
而不重命名东西吗?
您可以这样做:
struct Baz : public Foo, public Bar
{
using Bar::do_stuff;
using Foo::do_stuff;
//...
}
使用wandbox-gcc最新版本进行测试,编译良好。我认为函数重载也是如此,一旦重载了一个函数,就不能使用没有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
}
};
可能的相关问题
名称查找和重载解析不同。必须首先在作用域中找到名称,即我们必须找到一个X
,以便将名称do_stuff
解析为X::do_stuff
——与名称的使用无关——然后重载解析在X::do_stuff
的不同声明之间进行选择。
该过程不是识别所有可见的A::do_stuff
、B::do_stuff
等情况,然后在这些情况的并集之间执行过载解决。相反,必须为名称标识单个作用域。
在此代码中:
struct Baz : public Foo, public Bar
{
void func ()
{
do_stuff (1.1f); // ERROR HERE
}
};
Baz
不包含名称do_stuff
,因此可以查找基类。但是名称出现在两个不同的基中,所以名称查找无法识别作用域。我们从未达到超负荷解决的程度。
另一个答案中的建议修复有效,因为它将名称do_stuff
引入了Baz
的范围,并且还为该名称引入了2个重载。因此,名称查找确定do_stuff
意味着Baz::do_stuff
,然后过载解析从已知为Baz::do_stuff
的两个函数中进行选择。
顺便说一句,阴影是名称查找的另一个结果(本身不是规则(。名称查找选择内部作用域,因此外部作用域中的任何内容都不匹配。
当参数相关查找正在进行时,会出现更复杂的因素。简单地说,对于具有类类型参数的函数调用(如我的回答中所述的基本版本(,会多次进行名称查找,然后对每个参数的类型再次进行名称查找。然后,找到的作用域的并集进入重载集。但这并不适用于您的示例,因为您的函数只有内置类型的参数。
- C++无法定义虚拟函数 OUTER 类和头文件
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 尝试将unique_ptrs推送到向量时使用纯虚拟函数错误
- 有没有比在库中添加一个并非由所有派生类实现的新虚拟函数更好的设计实践
- 类型擦除的std::function与虚拟函数调用的开销
- 重写虚拟函数和继承
- 用纯虚拟函数兜圈子
- 为什么使用存储在虚拟方法表中的地址调用虚拟函数的函数会返回垃圾?
- 禁止子函数调用父级的抽象(或虚拟)函数
- 无法在子类中使用虚拟函数C++
- 无法在派生对象上运行虚拟函数
- 我可以调用从 main() 覆盖的虚拟函数吗?
- 在 C++ 中将函数获取和设置为虚拟函数
- 使用在堆栈上创建的对象调用虚拟函数
- 为什么在这种情况下不调用我的虚拟函数实现?
- 在C++中使虚拟函数私有化
- 模板继承类中的虚拟函数
- 为什么构造函数的虚拟函数调用有时有效,但其他调用却无效
- doxygenc++虚拟函数和实现
- 如何从派生类函数中调用虚拟函数