开发者

Multiple Inheritance Template Class

class messageA {
};

class messageB {
};

template<class T>
clas开发者_C百科s 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());
}

My first thought is, the above code should be fine, as class A will contains 2 overloaded submit functions, which will accept messageA and messageB object.

However, the compiler gives me the following error :

May I know why there is an ambiguous? Isn't it is quite obvious that, for the 1st submit call, I want to call messageA version? For the 2nd submit call, I want to call messageB version?


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


I have no compiler right now, but I guess one inheritance could hide the other : The compiler will use Koenig Lookup to find the right symbol, and if I remember correctly, once the compiler find a suitable symbol (i.e., a method called "submit"), it will stop searching for others in parent and/or outer scopes.

In this case, I thought both inheriting classes would be searched for the symbol, but without your exact compiler (Visual C++ 2003 ? 2008 ? 2010 ?), I cannot guess much more.

After some thoughts, another possibility is that the compiler did find both symbols, but is unable to decide which to call (at that moment of symbol resolution, the compiler cares only for symbol name, not its exact prototype). I believe this last explanation to be the right one.

Try adding using statements in your derived classes :

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

to bring both the submit methods directly in the A class scope.

Note, too, that your submit methods are taking messages as non-const reference, while in the constructor, your message parameters are temporaries (and thus, const r-values).

Re-writting the main as:

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

could help compile (this could explain the compiler error on line 22).

Or you could change the prototype of your submit methods to accept const references instead of non-const references.

Note: Still without compiler, so trying to brain-debug your code... :-P ...


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

The above code works fine.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜