Reputation: 105
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
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
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