多个继承模板类

时间:2010-07-29 09:05:38

标签: c++ multiple-inheritance ambiguous name-lookup class-members

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

我的第一个想法是,上面的代码应该没问题,因为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

2 个答案:

答案 0 :(得分:11)

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

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

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

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

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

将两个提交方法直接放在A类范围内。

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

将主要重写为:

int main()
{
    A aa;
    messageA mA ;
    messageA mB ;
    aa.submit(mA);
    aa.submit(mB);
}

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

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

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

答案 1 :(得分:1)

Something* smth1 = ((Base<Something> *)d)->createBase<Something>();

上面的代码工作正常。