跨基 类 解决虚方法重载

Resolving virtual method overloads across base classes

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);
}

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

error C2385: ambiguous access of 'foo'

could be the 'foo' in base 'base_1'

or could be the 'foo' in base 'base_2'

error C2660: 'base_1::foo' : function does not take 2 arguments

error C3861: 'foo': identifier not found

我知道我可以通过以下方式解决这个问题:

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

但是你可以想象,虚拟继承已经是我不得不忍受的太多罪过。我可能会写一个适配器。但我不明白是什么阻止了编译器尝试解析 base_2 中的 foo。我的同事认为这是一个编译器错误,但我不会很快责怪供应商。

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

根据标准,这确实是歧义,但您可以使用 using 或明确指定基数 class:

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声明

For the purpose of overload resolution, the functions which are introduced by a using-declaration into a derived class will be treated as though they were members of the derived class.

经验法则是不同范围内的函数不会重载 - 这里我们的 foo 处于不同的范围内。如果你想让它们过载,你需要用 using-declaration:

来引入它们
class join_1_2 : public virtual base_1, public virtual base_2
{
public:
    using base_1::foo;
    using base_2::foo;
};