Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I use the override keyword for multiple generic inheritance in C++?

I have a generic IDetachable interface, which provides one method:

template<class T>
class IDetachable {
public:
  virtual T detached() const = 0;
};

I have these example classes:

class A: public IDetachable<A> {
  virtual A detached() const override {
    // some implementation which returns a detached A object
  }
};

The problem occurs when inheriting B:

class B: public A, public IDetachable<B> {
  virtual B detached() const override {
    // some implementation which returns a detached B object
  }
};

clang++ tells me:

error: virtual function 'detached' has a different return type ('B')
  than the function it overrides (which has return type 'A')

To me it seems, that the compiler automatically chose the first parent for the override keyword. Is there any chance to tell the compiler which parent's method I intended to inherit with the override keyword?

like image 451
Polem Avatar asked Oct 07 '14 06:10

Polem


3 Answers

The problem isn't about how to override one or the other its the fact that you can't have two functions with the same signature and different return types.

Consider:

template<class T, class U>
class IDetachable {
public:
    virtual ~IDetachable() {}
    virtual T detached() const = 0;
    virtual U detached() const = 0; // whoopse problem
};

It doesn't matter how you end up with two same-signature functions returning different types its always illegal.

@AdrianMay provides a working answer. He changes the signatures of the functions.

like image 153
Galik Avatar answered Nov 11 '22 02:11

Galik


You could pass a dummy T to detach:

template<class T>
class IDetachable {
public:
  virtual T detached(T*dummy) const = 0;
};

You ignore that parameter but now you can specialise on it.

like image 33
Adrian May Avatar answered Nov 11 '22 02:11

Adrian May


Do you just want return type covariance? It works only on pointers and references:

template<class T>
class IDetachable {
public:
    virtual T* detached() const = 0;
};


class A: public IDetachable<A> {
    virtual A* detached() const override {
        // some implementation which returns a detached A object
    }
};

class B: public A, public IDetachable<B> {
    virtual B* detached() const override {
        // some implementation which returns a detached B object
    }
};

int main() {
    IDetachable<A> *da = new A;
    A *a = da->detached();
    IDetachable<B> *db = new B;
    B *b = db->detached();
}
like image 2
yuri kilochek Avatar answered Nov 11 '22 03:11

yuri kilochek