Search code examples
c++templateschainingcrtpfluent-interface

method chaining child with parent classes using c++


Is there a way to chain calls to superclass from subclass without casting, overriding the method or using interfaces. E.g. when doing

class A {
public: 
    A& foo() { return *this; }
};

class B : public A {
public:
    B& bar() { return *this; }
};

int main(void) {
    B b;
    b.foo().bar();
    return 0;
}

When compiling with clang I'm getting the error

main.cpp:13:10: error: no member named 'bar' in 'A'
        b.foo().bar();
        ~~~~~~~ ^
1 error generated.

Which I can see why (since A returns reference to self), but I would like it to return it's subclass type B since it is called in that context. Is this possible? Or do I need to define B as

class B : public A {
public:
    B& bar() { return *this; }
    B& foo() { A::foo(); return *this; }
};

and make foo() virtual?


Solution

  • You can use CRTP pattern:

    template<class Derived>
    class A {
    public:
        Derived& foo() { return *static_cast<Derived*>(this); }
    };
    
    class B : public A<B> {
    public:
        B& bar() { return *this; }
    };
    
    int main(void) {
        B b;
        b.foo().bar();
        return 0;
    }