Multiple inheritance pattern templates

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

My first thought is that the code above should be accurate, since class A will contain two overloaded send functions that will accept messageA and messageB objects.

However, the compiler gives me the following error:

Can I find out why there is ambiguity? Is it not obvious that for the first transfer request I want to call the messageA version? For the second send request, do 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 
+7
c ++ multiple-inheritance ambiguous name-lookup class-members
source share
2 answers

I don’t have a compiler right now, but I think that one inheritance may hide another: the compiler will use Koenig Lookup to find the correct character, and if I remember correctly, as soon as the compiler finds a suitable character (i.e. a method called " submit "), it will stop searching for others in the parent and / or external areas.

In this case, I thought that both inheritance classes would look for a character, but without your exact compiler (Visual C ++ 2003? 2008? 2010?), I can't guess much more.

After some thoughts, another possibility is that the compiler found both characters, but cannot decide which call (at this point in resolving the character, the compiler only cares about the name of the character, not its exact prototype). I believe that this last explanation will be correct.

Try adding with operators to derived classes:

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

to bring both dispatch methods directly to class A scope.

Also note that your sending methods accept messages as non-constant links, while in the constructor your message parameters are temporary (and therefore constant values ​​of r).

Repeatedly name main as:

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

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

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

Note: still without a compiler, so try to debug your code ...: -P ...

+11
source share
 Something* smth1 = ((Base<Something> *)d)->createBase<Something>(); 

The above code is working fine.

+1
source share

All Articles