1

I am wondering why the follow does not work:

template<typename Derived>
struct Base0 {
    const auto& derived() { return static_cast<const Derived& >(*this);}
}

template<typename Derived>
struct Base1: Base0<Base1<Derived>> {
    auto foo () { return derived().foo_impl();}
}

struct Foo: Base1<Foo>> {
    auto foo_impl () { return "foo";}
}

It complains that derived() is not a member. Changing derived() to this->derived() works, but I guess this will get Base1<Base0<Foo>>& instead of Foo& (which is not desired), right?

Alternatively, we can do the follow:

template<typename Derived>
struct Base0 {
    const auto& derived() { return static_cast<const Derived& >(*this);}
}

template<typename Derived>
struct Base1: Base0<Derived> {
    // for some reason, "this->" is still needed here, why??? 
    auto foo () { return this->derived().foo_impl();}
}

struct Foo: Base1<Foo>> {
    auto foo_impl () { return "foo";}
}

But I am not sure if this is the conventional way of doing multilevel inheritance using CRTP. Any comments?

Jerry Ma
  • 511
  • 4
  • 15
  • 3
    `derived` is a dependant type name and so requires `this->` or `Base0>::` – Jarod42 Aug 16 '19 at 19:16
  • There is not real conventionnal way. This is more of an opinion matter than technical – Guillaume Racicot Aug 16 '19 at 19:17
  • I can't believe it is not a duplicate, yet I can't find one. – SergeyA Aug 16 '19 at 19:21
  • 1
    Possible duplicate of [Where and why do I have to put the "template" and "typename" keywords?](https://stackoverflow.com/questions/610245/where-and-why-do-i-have-to-put-the-template-and-typename-keywords) (the question is not about `typename` or `template` *per se*, but the root cause is the same -- dependent name.) – L. F. Aug 16 '19 at 20:42

0 Answers0