Is there a way for a CRTP base class to access types in derived class?

I’m trying to access a derived class type from inside a CRTP base, such as:

template <typename CRTP>
class Base {
   using Type = typename CRTP::Type;

   void method(const Type& t) {
      do_something();
      static_cast<CRTP&>(*this).derived_method( t );
   }

   void do_something() {
   }
};

class Derived : public Base<Derived> {
   using Type = int;

   void derived_method(const Type& t ) {
   }
};

which doesn’t work because CRTP is incomplete in the declaration of Base. I understand the error. Is there a reasonable workaround to get a similar effect?

I see a similar question at C++ static polymorphism (CRTP) and using typedefs from derived classes, but that solution doesn’t work in my case. For that question, the base class was looking for a template parameter of Derived, not an internal type, so a traits class was able to get at the type without looking inside the declaration of Derived.

Everything I can come up with involves repeating the definition of Derived::Type = int in one way or another instead of using what’s already in Derived.

>Solution :

I’m not entirely sure if this is what you need, but it’ll delay the use of the CRTP class until it’s complete:

#include <type_traits>

template <typename CRTP>
class Base {
public:
    void method(const auto& t) {
        static_assert(std::is_same_v<std::remove_cvref_t<decltype(t)>,
                                     typename CRTP::Type>);

        do_something();
        static_cast<CRTP&>(*this).derived_method(t);
    }

    void do_something() {
    }
};

Leave a Reply