多个继承模板类

Che*_*eng 7 c++ multiple-inheritance ambiguous class-members name-lookup

class messageA {
};

class messageB {
};

template<class T>
class queue {
public:
    virtual ~queue() {}
    void submit(T& x) {}
};

class A : public queue<messageA>, public queue<messageB>
{
};

int main()
{
    A aa;
    aa.submit(messageA());
    aa.submit(messageB());
}
Run Code Online (Sandbox Code Playgroud)

我的第一个想法是,上面的代码应该没问题,因为A类将包含2个重载的提交函数,它们将接受messageA和messageB对象.

但是,编译器给出了以下错误:

我可以知道为什么会有歧义吗?是不是很明显,对于第一次提交电话,我想打电话给messageA版本?对于第二次提交电话,我想打电话给messageB版本?


------ Build started: Project: main, Configuration: Release Win32 ------
Compiling...
main.cpp
.\main.cpp(21) : error C2385: ambiguous access of 'submit'
        could be the 'submit' in base 'queue<messageA>'
        or could be the 'submit' in base 'queue<messageB>'
.\main.cpp(21) : error C3861: 'submit': identifier not found
.\main.cpp(22) : error C2385: ambiguous access of 'submit'
        could be the 'submit' in base 'queue<messageA>'
        or could be the 'submit' in base 'queue<messageB>'
.\main.cpp(22) : error C2664: 'queue<T>::submit' : cannot convert parameter 1 from 'messageB' to 'messageA &'
        with
        [
            T=messageA
        ]
.\main.cpp(22) : error C3861: 'submit': identifier not found
Run Code Online (Sandbox Code Playgroud)

pae*_*bal 11

我现在没有编译器,但我想一个继承可以隐藏另一个:编译器将使用Koenig Lookup找到正确的符号,如果我没记错的话,一旦编译器找到合适的符号(即一个名为"submit"的方法) "),它将停止在父和/或外部范围内搜索其他人.

在这种情况下,我认为继承类都将被搜索符号,但没有你的确切编译器(Visual C++ 2003?2008?2010?),我猜不到更多.

经过一些思考,另一种可能性是编译器确实找到了两个符号,但是无法决定调用哪个(在符号解析的那一刻,编译器只关心符号名称,而不是它的确切原型).我相信这最后的解释是正确的.

尝试在派生类中添加using语句:

class A : public queue<messageA>, public queue<messageB>
{
   using queue<messageA>::submit ;
   using queue<messageB>::submit ;
} ;
Run Code Online (Sandbox Code Playgroud)

将两个提交方法直接带入A类范围.

另请注意,您的提交方法将消息作为非const引用,而在构造函数中,您的消息参数是临时值(因此,const r值).

将主要重写为:

int main()
{
    A aa;
    messageA mA ;
    messageA mB ;
    aa.submit(mA);
    aa.submit(mB);
}
Run Code Online (Sandbox Code Playgroud)

可以帮助编译(这可以解释第22行的编译器错误).

或者您可以更改提交方法的原型以接受const引用而不是非const引用.

注意:仍然没有编译器,所以试图对你的代码进行大脑调试...... :-P ...