c++templatescrtp

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() {
        }
    };