Столкновение имени функции множественного наследования в C ++ - PullRequest
3 голосов
/ 30 марта 2012

Контекст: я обсуждал C # и Java на работе, когда возник следующий вопрос, и я подумал, как (или если) это можно было бы элегантно решить в C ++.

Допустим, у вас есть два класса A и B (детали которых не важны), а затем два шаблонных класса G и H, описанные как что-то вроде:

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

Тогда у нас есть классы C и D, описанные как:

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

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

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

Я хочу иметь возможность вызвать C метод foo из G<A> и foo из G<B>. И я хочу иметь возможность переопределить для D метод foo из H<A> и H<B>.

В конце я хочу использовать C и D, как в следующих примерах:

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

Всегда есть способы сделать это (и у меня есть некоторые идеи), но меня интересует список изящных и безопасных способов сделать это, включая плюсы и минусы.

Итак, как бы вы это сделали?

Ответы [ 2 ]

5 голосов
/ 30 марта 2012

Два способа, о которых я могу думать:

C x;

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

То есть: либо явно указывать имя функции, либо использовать значение в иерархии типов.

1 голос
/ 30 марта 2012

Как насчет перегрузки и использования разных аргументов:

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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...