简体   繁体   中英

Implementing a "virtual" method returning *this (covariant return type)

I'm writing a hierarchy of classes of C++, let's say A , B inheriting A , C inheriting A , and D inheriting B .

Now, all of these classes must have a method bar() & , whose body is:

{
    A::foo();
    return *this;
}

It's the exact same code, doing the exact same thing - except for the type of the return value - which returns an lvalue reference to the class' type.

Now, the signature of this method would be different for every class. But - it's essentially the same method. The thing is, the way things stand, I need to replicate the code for it many times. How can I avoid this code duplication?

I was thinking of writing some mixin with CRTP, but when I get into the details it becomes super-ugly.

Note: For the purposes of this example, bar() is only defined for lvalues so as not to get into the question of legitimacy of returning *this from an rvalue.

As Raymond Chen commented, c++23 would have deducing this which allows code like:

struct A
{
    template <typename Self>
    Self& bar(this Self& self) // Here self is the static type which calls bar
                               // so potentially the derived type
    {
        self.A::foo(); // or self.foo();
        return self;
    }
    // ...
};
struct B : A{};
struct C : A{};
struct D : B{};

But currently, CRTP might help, something like:

struct A
{
    // ...
};


template <typename Derived, typename Base>
struct A_CRTP : Base
{
    Derived& bar()
    {
        A::foo();
        return static_cast<Derived&>(*this);
    }
    // ...
};
struct B : A_CRTP<B, A> {};
struct C : A_CRTP<C, A> {};
struct D : A_CRTP<D, B> {};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM