CRTP with Protected Derived Member

前端 未结 3 713
半阙折子戏
半阙折子戏 2021-01-30 11:19

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

3条回答
  •  离开以前
    2021-01-30 11:52

    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 
    struct Interface
    {
        using CRTP = Interface; //Magic!
        void f() { static_cast(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
    {
        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