Somesh
Somesh

Reputation: 105

Derive a template class from itself in C++

In a portion of legacy code that I have been asked to work with, I have come across a concept that I don't understand. Searching in SO and googling didn't quite help, hence this question.

There is a template class that looks like this:

template<int Index_t, int Kind_t, ProtocolType Prot_t, class Protocol>
class CommandHandlerGeneric 
   : private CommandHandlerGeneric<Index_t-1, Kind_t, Prot_t, Protocol> {
public:
   CommandHandlerGeneric(Protocol& Shared, CmdHandlerBase** Cont) :
      CommandHandlerGeneric<Index_t-1, Kind_t, Prot_t, Protocol>(Shared, Cont) {}
};

The CmdHandlerBase class is a non-template class that exists elsewhere in a different header. Following the above definition, there is a macro that looks like this:

#define REGISTER_COMMAND_HANDLER_BASE(CmdIndex, CmdType, CmdKind, ProtType) \
    template<class Protocol> \
    class CommandHandlerGeneric<CmdIndex, CmdKind, ProtType, Protocol>
       : private CommandHandlerGeneric<CmdIndex-1, CmdKind, ProtType, Protocol> \
    { \
       CmdType m_Cmd;\
     public: \
       CommandHandlerGeneric(Protocol& Shared, CmdHandlerBase** Cont) : \
         m_Cmd(Shared), \
         CommandHandlerGeneric<CmdIndex-1, CmdKind, ProtType, Protocol>(Shared, Cont) \
       { Cont[CmdIndex] = &m_Cmd; } \
    };

Looks like the above macro partially specializes the class template CommandHandlerGeneric. Is this correct? What is the rationale behind deriving a class privately from itself?

Upvotes: 6

Views: 863

Answers (2)

Bj&#246;rn Pollex
Bj&#246;rn Pollex

Reputation: 76788

I can't really make anything of your specific example, but in general, that is a recursive class-template. There should be a specialization around for Index_t = x, which would terminate the recursion.

The second ingredient here is private inheritance, which can be thought of as a form of composition. Combined with a recursive template, you can use this to create a class of variable sizes, for instance a vector of a certain dimension.

Upvotes: 3

sharptooth
sharptooth

Reputation: 170499

Note this:

template<int Index_t, int Kind_t, ProtocolType Prot_t, class Protocol>
class CommandHandlerGeneric 
    : private CommandHandlerGeneric<Index_t-1, Kind_t, Prot_t, Protocol>

The first template parameter is altered. It's not the same class anymore. A class template is not a complete class until all parameters are specified.

Indeed, it's illegal to inherit from the same class template and pass the very same set of parameters, but that's not the case here.

Upvotes: 2

Related Questions