c++thisvirtual-functionsself-referenceexplicit-object-parameter

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.


Solution

  • 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> {};