Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to inherit a member function so that it always returns a reference to the derived instance?

I'm working on an iterator family, where all iterator classes X have X& operator++() {++x; return *this} in common, so it seems to be a good idea to place it in a common base class. Unfortunately, the return type changes, since it should always return a reference to the derived class.

The following illustrates the problem. I would like f() to work, but the only workarounds I could come up with are g() and h(), which are not satisfactory:

struct A {
    A& f() {return *this;}

    template <typename T>
    T& g() {return *(T*)this;}

    template <typename T>
    T& h(T& unused) {return *(T*)this;}
};

struct B : A {
    int x;
    B(int x) : x(x) {}
};

int main() {
    B b(12);

    //B b1 = b.f();   // error: conversion from 'A' to non-scalar type 'B' requested

    B b2 = b.g<B>();  // works
    B b3 = b.h(b);    // works
}

Is there a way to make B b1 = b.f(); work? Maybe using C++11 features?

like image 417
Stefan Avatar asked Dec 11 '22 05:12

Stefan


1 Answers

Use CRTP:

template<class Derived>
struct A {
    Derived& f() {return static_cast<Derived&>(*this);}
};

struct B : A<B> {
    int x;
    B(int x) : x(x) {}
};
like image 114
ecatmur Avatar answered Jan 18 '23 23:01

ecatmur