CRTP with Protected Derived Member

crtp mixin
crtp constructor
curiously recurring template pattern java
crtp protocol
c++ crtp factory
c++ template inheritance
c++ template base class
crtp in container

In the CRTP pattern, we run into problems if we want to keep the implementation function in the derived class as protected. We must either declare the base class as a friend of the derived class or use something like this (I have not tried the method on the linked article). Is there some other (simple) way that allows keeping the implementation function in the derived class as protected?

Edit: Here is a simple code example:

template<class D> 
class C {
public:
    void base_foo()
    {
        static_cast<D*>(this)->foo();
    }
};


class D:  public C<D> {
protected: //ERROR!
    void foo() {
    }   
};

int main() {
    D d;
    d.base_foo();
    return 0;
}

The above code gives error: ‘void D::foo()’ is protected with g++ 4.5.1 but compiles if protected is replaced by public.

It's not a problem at all and is solved with one line in derived class:

friend class Base< Derived >;

#include <iostream>

template< typename PDerived >
class TBase
{
 public:
  void Foo( void )
  {
   static_cast< PDerived* > ( this )->Bar();
  }
};

class TDerived : public TBase< TDerived >
{
  friend class TBase< TDerived > ;
 protected:
  void Bar( void )
  {
   std::cout << "in Bar" << std::endl;
  }
};

int main( void )
{
 TDerived lD;

 lD.Foo();

 return ( 0 );
}

Better Encapsulation for the Curiously Recurring Template , One of the oldest is the curiously recurring template pattern (CRTP) identified by When a friend or a member function of a derived class references a protected  I'm using CRTP, and I have a problem with accessing the protected members of derived class. Here is example, close to my code: template< typename Self> class A { public: void foo(

As lapk recommended, problem can be solved with simple friend class declaration:

class D:  public C<D> {
    friend class C<D>;      // friend class declaration
protected:
    void foo() {
    }
};

However, that exposes all protected/private members of derived class and requires custom code for each derived class declaration.

The following solution is based on the linked article:

template<class D>
class C {
public:
    void base_foo() { Accessor::base_foo(derived()); }
    int base_bar()  { return Accessor::base_bar(derived()); }

private:
    D& derived() { return *(D*)this; }

    // accessor functions for protected functions in derived class
    struct Accessor : D
    {
        static void base_foo(D& derived) {
            void (D::*fn)() = &Accessor::foo;
            (derived.*fn)();
        }
        static int base_bar(D& derived) {
            int (D::*fn)() = &Accessor::bar;
            return (derived.*fn)();
        }
    };
};

class D : public C<D> {
protected: // Success!
    void foo() {}
    int bar() { return 42; }
};

int main(int argc, char *argv[])
{
    D d;
    d.base_foo();
    int n = d.base_bar();
    return 0;
}

PS: If you don't trust your compiler to optimize away the references, you can replace the derived() function with the following #define (resulted in 20% fewer lines of disassembly code using MSVC 2013):

    int base_bar() { return Accessor::base_bar(_instance_ref); }

    private:
    #define _instance_ref *static_cast<D*>(this)   //D& derived() { return *(D*)this; }

Curiously recurring template pattern, Say, you have 3 classes, A, B, C, and that C is derived from B which is This is part of the Programmer's Rights, protected by the Constitution of C++: no A needs some code behind the method helperFunction1 , which is  If the derived class calls an inherited function which then calls another member function, that function will never call any derived or overridden member functions in the derived class. However, if base class member functions use CRTP for all member function calls, the overridden functions in the derived class will be selected at compile time.

After some I came with a solution that works event for private members of templated derived classes. It does not solves the problem of not exposing all the members of the derived class to the base, since it uses a friend declaration on the whole class. On the other hand, for the simple case, this does not requires repeating the base name, nor it's template parameters and will always work.

First the simple case when the derived is non-template. The base takes an additional void template parameter just to show that everything still works in the case of extra template parameters of the base. The only needed one, as per the CRTP, is the typename Derived.

//Templated variadic base
template <typename Derived, typename...>
struct Interface
{
    using CRTP = Interface; //Magic!
    void f() { static_cast<Derived*>(this)->f(); }
};

//Simple usage of the base with extra types
//This can only be used when the derived is NON templated
class A : public Interface<A, void>
{
    friend CRTP;
    void f() {}
};

The only thing needed for this to work is the using CRTP = Interface; declaration in the base and the friend CRTP; declaration in the derived.

For the case when the derived is itself templated the situation is trickier. It took me some time to come to the solution, and I'm sure it's still not perfect.

Most of the magic happens inside these templates:

namespace CRTP
{
    template <template <typename, typename...> class _Base, typename _Derived, typename... _BaseArgs>
    struct Friend { using Base = _Base<_Derived, _BaseArgs...>; };

    template <template <typename, typename...> class _Base, typename ..._BaseArgs>
    struct Base
    {
        template <template <typename...> class _Derived, typename... _DerivedArgs>
        struct Derived : public _Base<_Derived<_DerivedArgs...>, _BaseArgs...> {};
    };
}

Their usage is more or less straightforward. Two use the above templates several steps are needed.

First, when inheriting in the derived class the inherited-from base class, and it's optional parameters, needs to be given. This is done using CRTP::Base<MyBase, BaseOptional....>, where MyBase is the name of the class used for CRTP, and the BaseOptional... are template parameters that are passed to the base class as-is, directly after passing our derived class that is supplied in the next step. When the base class does not accepts any additional template parameters they can be omitted completely: CRTP::Base<MyBase>.

The next step is to introduce the derived class (the whole point of CRTP). This is done by following the above CRTP::Base<...> with a ::Derived<ThisDerived, DerivedOptional...>. Where ThisDerived is the class this is defined in, and DerivedOptional... are all the template parameters declared in this class'es template declaration. The optional parameters much be specified exactly as they appear in the class template declaration.

The last step is declaring the base class as a friend. This is done by declaring friend typename CRTP::Friend<MyBase, ThisDerived, BaseOptional...>::Base somewhere in the class. The BaseOptional... template perameters must be repeated exactly as they appear in the CRTP::Base<MyBase, BaseOptional...> that is inherited from.

Follows is an example of using a templated derived when the base does not depends on the templated types (but it still can take other template parameters, void in this example).

//Templated derived with extra, non-dependant types, passed to the base
//The arguments passed to CRTP::Base::Derived<, ARGS> must exactly match
//  the template
template <typename T, typename... Args>
class B : public CRTP::Base<Interface, void>::Derived<B, T, Args...>
{
    friend typename CRTP::Friend<Interface, B, void>::Base;
    void f() {}
};

Next is an example for when the base depends on template parameters of the derived. The only difference from the previous example is the template keyword. An experiment shows that if the keyword is specified for the previous, non dependant, case the code also complies cleanly.

//Templated derived with extra dependant types passed to the base
//Notice the addition of the "template" keyword
template <typename... Args>
class C : public CRTP::Base<Interface, Args...>::template Derived<C, Args...>
{
    friend typename CRTP::Friend<Interface, C, Args...>::Base;
    void f() {}
};

Please note that these templates do not work for non-templated derived classes. I will update this answer when I find the solution, so a unified syntax could be used for all cases. The closest thing that can be done is just using some fake template parameter. Note that it still must be named and passed to the CRTP machinery. For example:

template <typename Fake = void>
class D : public CRTP::Base<Interface>::Derived<D, Fake>
{
    friend typename CRTP::Friend<Interface, D>::Base;
    void f() {}
};

Note that A, B, C & D are declared as class. That is, all their members are private.

Follows is some code that uses the above classes.

template <typename... Args>
void invoke(Interface<Args...> & base)
{
    base.f();
}

int main(int, char *[])
{
    {
        A derived;

        //Direct invocation through cast to base (derived.f() is private)
        static_cast<A::CRTP &>(derived).f();

        //Invocation through template function accepting the base
        invoke(derived);
    }

    {
        B<int> derived;
        static_cast<B<int>::CRTP &>(derived).f();
        invoke(derived);
    }

    {
        C<void> derived;
        static_cast<C<void>::CRTP &>(derived).f();
        invoke(derived);
    }

    {
        D<void> derived;
        static_cast<D<>::CRTP &>(derived).f();
        invoke(derived);
    }

    return 0;
}

The invoke free-standing templated function works for any class derived from the base. Also shown is how to cast the derived to the base without the need to actually specify the name of the base. Surprisingly, this does not depend on any system headers.

The full code is available here: https://gist.github.com/equilibr/b27524468a0519aad37abc060cb8bc2b

Comments and corrections are welcome.

How to Turn a Hierarchy of Virtual Methods into a CRTP, After having defined the basics on CRTP in episode #1 of the series, let's consider Why not use template non-member functions that could operate on any In this regard, the derived class offers an interface to the base class. You can see this by changing the access in the derived classes to protected. Protected members that are not declared as static are accessible to friends and member functions in a derived class only through a pointer to, reference to, or object of the derived class. For related information, see friend , public , private , and the member-access table in Controlling Access to Class Members .

What the Curiously Recurring Template Pattern can bring to your , Not even accessing the members of a derived class. The CRTP is an idiom in C++ in which a class let's call it X derives from a class { ++_createdObjects; ++_aliveObjects; } protected: ~counter() // objects should never be  CRTP with Protected Derived Member (1) It's not a problem at all and is solved with one line in derived class: friend class Base< Derived >; #include <iostream

The Curiously Recurring Template Pattern (CRTP), members. It adds boilerplate. Worst, it's impossible in multi-level CRTP: > the derived class must know the specific base wanting friendship. After reading the posts on the curiously recurring template pattern, I’m wondering how to (expressively) implement this with 3 or more classes. Say, you have 3 classes, A, B, C, and that C is derived from B which is derived from A, and, say, both B and A used to be pure virtual classes.

CRTP access, The short answer is yes, just make them public in the base class. Inherited constructors have the same accessibility in the derived class as they  A protected member is accessible within its class and by derived class instances. For a comparison of protected with the other access modifiers, see Accessibility Levels. Example. A protected member of a base class is accessible in a derived class only if the access occurs through the derived class type. For example, consider the following code

Comments
  • Are you talking about something other than public interface/protected implementation, which would be my first suggestion? Can you provide a more concrete example of the higher-level problem you're trying to solve with CRTP?
  • Isn't this what virtual functions are for?
  • @BoPersson, virtual functions are for run-time polymorphism, CRTP is for compile-time polymorphism. There's room in the world for both. See en.wikipedia.org/wiki/Curiously_recurring_template_pattern
  • @Mark - There sure is, but if the requirement is to call a protected function in a derived class, virtuals look like a good fit. :-)
  • ^ Not when the CRTP is often used to avoid virtuals. Anyway, I really don't see a question here. It only briefly mentioned the usual method of using friend, then asked whether something else was available, without explaining what's wrong with the established solution.