C ++ multiple inheritance of name collision function

Context: I was discussing how C # and Java work at work when the next question came up and I wondered how (or if) it could be elegantly resolved in C ++.

Let's say you have two classes A

and B

(the details of which are not important), and then two template classes G

and H

are described something like:

template <typename T>            | template <typename T> 
class G                          | class H
{                                | {
   public :                      |    public :
      T * foo() ;                |       virtual T * foo() = 0 ;
      // etc.                    |       // etc.
} ;                              | } ;

      

Then we have a class C

and D

, described as:

class A { /* ... */ } ;
class B { /* ... */ } ;

class C : public G<A>, public G<B>
{
} ;

class D : public H<A>, public H<B>
{
   // ???
} ;

      

I want to be able to call a C

method foo

from G<A>

and foo from G<B>

. And I want to be able to override for a D

method foo

from H<A>

and H<B>

.

Eventually, I want to be able to use C and D like in the following examples:

C c ;
A * a = c.??? ; (I want to call G<A>::foo())
B * b = c.??? ; (I want to call G<B>::foo())

D d ;
A * a = c.??? ; (I want to call H<A>::foo())
B * b = c.??? ; (I want to call H<B>::foo())

      

There are always ways to do this (and I have some ideas), but I'm interested in a list of elegant and safe ways to do this, including pros and cons.

So how would you go about it?

+3


source to share


2 answers


Two ways I can think of:

C x;

x.G<A>::foo(); // 1
static_cast<G<A>&>(x).foo(); // 2

      



That is: either explicitly assign a name to the function, or degenerate into a type hierarchy.

+5


source


How about overloading and using different arguments:



template <typename T>
class G
{
public:
    T * foo(T &a) {/* ... */};
    // etc.
};

class A
{
public:
    /* ... */
};

class B
{
    public:
    /* ... */
};

class C : public G<A>, public G<B>
{
public:
    using G<A>::foo;
    using G<B>::foo;

};

int main()
{
    C c;

    A a;
    B b;

    c.foo(a);
    c.foo(b);

    return 0;
}

      

+1


source







All Articles