正在解决跨基类的虚拟方法重载

Resolving virtual method overloads across base classes

本文关键字:虚拟 方法 重载 基类 解决      更新时间:2023-10-16

Visual Studio 2013。

给定:

class base_1
{
public:
    virtual void foo(int) = 0;
};
class base_2
{
public:
    virtual void foo(int, double) = 0;
};
class join_1_2 : public virtual base_1, public virtual base_2
{};

我有一个水槽:

void sink(join_1_2 &param)
{
    param.foo(42, 3.14);
}

但我得到以下编译器错误:

错误C2385:"foo"的访问不明确

可能是基"base_1"中的"foo"

或者可以是基础"base_2"中的"foo"

错误C2660:"base_1::foo":函数不接受2个参数

错误C3861:"foo":找不到标识符

我知道我可以用解决这个问题

param.base_2::foo(42, 3.14);

但正如你所能想象的,虚拟继承已经是我不得不忍受的一种罪过。我可能要写一个适配器。但我不明白是什么阻止编译器尝试在base_2中解析foo。我的同事认为这是一个编译器错误,但我并没有那么快责怪供应商。

C++规范对跨基类解决重载虚拟方法有何规定?

根据标准,这确实是模糊的,但您可以使用using或显式指定基类:

class join_1_2 : public virtual base_1, public virtual base_2
{
public:
    using base_1::foo;
    using base_2::foo;
};
void sink(join_1_2 &param)
{
    param.base_2::foo(42, 3.14);
}

7.3.3使用声明

为了解决过载问题,通过using声明引入到派生类将被视为派生类的成员。

经验法则是不同作用域中的函数不会重载-这里我们的foo位于不同的作用域中。如果你想让它们过载,你会想用使用声明将它们引入:

class join_1_2 : public virtual base_1, public virtual base_2
{
public:
    using base_1::foo;
    using base_2::foo;
};