解决跨基类的虚方法重载

时间:2015-12-16 23:01:42

标签: c++ multiple-inheritance name-lookup ambiguous-call

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 ++规范如何解决跨基类解析重载虚拟方法的问题?

2 个答案:

答案 0 :(得分:4)

根据标准确实存在歧义,但您可以使用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声明引入的函数   派生类将被视为派生类的成员。

答案 1 :(得分:4)

经验法则是,不同范围内的函数不会超载 - 这里我们的Unique处于不同的范围内。如果您希望它们超载,您需要使用 using-declaration 来引入它们:

foo