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?
Deriving from a non-template base classIt is quite possible to have a template class inherit from a 'normal' class. This mechanism is recommended if your template class has a lot of non-template attributes and operations. Instead of putting them in the template class, put them into a non-template base class.
Explanation: Class derived template is derived from regular non-templated C++ class or templated class.
Definition. As per the standard definition, a template class in C++ is a class that allows the programmer to operate with generic data types. This allows the class to be used on many different data types as per the requirements without the need of being re-written for each type.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With