error C2385问题的记录:多继承的歧义

原因

在给一个模块写单测时,发现一个有多继承的类出现了如下的报错(Visual studio 2019)

error C2385: ambiguous access of 'function'
message: could be the 'function' in base 'Base1'
message: or could be the 'function' in base 'Base2'

类的继承结构是这样的,Inner/Base1/Base2三个类都是抽象类。Base1和Base2有同名函数function。

classDiagram Base1:(virtual void function(EnumB) = 0) Base2:(virtual void function(EnumC) = 0) Base1 <|-- Inner Base2 <|-- Inner Inner <|-- Derived Derived: function(EnumB) Derived: function(EnumC)
#include <iostream>

typedef enum {
    EWithB_1,
    EWithB_2
} EnumB;

typedef enum {
    EWithC_1,
    EWithC_2
} EnumC;

class Base1 {
public:
    virtual ~Base1() {}
    virtual void function(EnumB eb_v) = 0;
};

class Base2 {
public:
    virtual ~Base2() {}
    virtual void function(EnumC ec_v) = 0;
};

class Inner : public Base1, public Base2 {
public:
    virtual ~Inner() {}
    virtual void test() = 0;
    // Remove annotation to build successfully.
    // using Base1::function;
    // using Base2::function;
};

class Derived : public Inner {
public:
    void test() {std::cout << "test" << std::endl;}
    void function(EnumB eb_v) {std::cout << "From B" << eb_v << std::endl; }
    void function(EnumC ec_v) {std::cout << "From C" << ec_v << std::endl; }
};

void CreateInner(Inner* inner) {
    inner = new Derived;
}

int main() {
    Inner *i = new Derived;
    i->function(EWithB_1);
    i->function(EWithC_2);
}

这段代码中,Inner是抽象类,并没有对function的实现,而类Derived中对应的function是针对具体枚举类型的。本来以为Derived当中已经有了实现,为什么编译器还会分不清呢?仔细看了一下才发现,对外只提供了Inner作为接口(CreateInner),因此当Inner调用function时,编译器无法确定调用哪个function。

解决

在Inner类中声明命名空间

class Inner : public Base1, public Base2 {
public:
    virtual ~Inner() {}
    virtual void test() = 0;
    using Base1::function;
    using Base2::function;
};

reference

Compiler Error C2385

error C2385问题的记录:多继承的歧义