C ++ How are multiple inheritance from interfaces with different return types?

Perhaps I have two interfaces with the same function names and parameters, but with different return values:

struct A { virtual void foo() = 0; }; struct B { virtual int foo() = 0; }; 

How to define a class C that inherits these interfaces (if possible)? For example, I am writing some kind of pseudo code that is not compiled:

 // this code is fake, it doesn't compiled!! struct C : A, B { // how to tell compiler what method using if referenced from C? using void foo(); // incorrect in VS 2012 // and override A::foo() and B::foo()? virtual void foo() { std::cout << "void C::foo();\n"; } // incorrect virtual int foo() { std::cout << "int C::foo();\n"; return 0; } // incorrect } // ... for use in code C c; A &a = c; B &b = c; c.foo(); // call void C::foo() when reference from C instance a.foo(); // call void C::foo() when reference from A instance b.foo(); // call int C::foo() when reference from B instance 
+7
source share
4 answers

This is not possible, but not because of multiple inheritance. The ambiguity arises from the invalid overload of foo in class C You cannot have both int foo() and void foo() , since the return type is not part of the function signature, so the compiler will not be able to resolve foo calls. You can look at your interface as a union of classes A and B , so logically the problem is already present before the actual inheritance. Since there are 2 different and unrelated types from the perspective of the compiler A and B are no problems compiling them, and the error is delayed until the actual unification in class C

More on function signatures and overloads: Is part of the return type of a function signature?

+4
source

You can clearly qualify.

 class C : A, B { public: void A::foo() { ... } int B::foo() { ... } }; 

Edit:

This is most likely an MSVC extension, not a standard one.

+2
source

It is not possible to overwrite the type of the returned virtual function using the same signature (as @icepack's answer explains).

An alternative approach might be to have a base class class declaring foo() with the return type specified as the template parameter, and providing specializations for specific types of return parameters.

This will be a summary of @Dietmar Kühl's suggestion.

+1
source

What you can do is put all the common materials in the virtual database, say C_base and override the conflicting virtual functions in the helper classes. Since the common stuff for C readily available in C_base , it essentially resembles the most derived C Finally, you are a C class simply because the class pulls things together:

 struct A { virtual void foo() = 0; }; struct B { virtual int foo() = 0; }; struct C_base { int all_data; }; struct A_aux: virtual C_base, A { void foo() { std::cout << "A_aux::foo()\n"; } }; struct B_aux: virtual C_base, B { int foo() { std::cout << "B_aux::foo()\n"; return 0; } }; struct C : A_aux, B_aux { using A_aux::foo; }; 
+1
source

All Articles