Наследование класса шаблона от самого себя в C++

в части устаревшего кода, с которым меня попросили работать, я столкнулся с концепцией, которую я не понимаю. Поиск в SO и googling не совсем помогли, поэтому этот вопрос.

существует класс шаблона, который выглядит следующим образом:

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) {}
};

на CmdHandlerBase class-это класс без шаблона, который существует в другом месте в другом заголовке. Следуя приведенному выше определению, существует макрос, который выглядит следующим образом:

#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; } 
    };

выглядит как выше макрос частично специализируется на шаблоне класса CommandHandlerGeneric. Правильно ли это? Каково обоснование частного вывода класса из самого себя?

2 ответов


Я не могу ничего сделать из вашего конкретного примера, но в целом это рекурсивный шаблон класса. Должна быть специализация вокруг Index_t = x, который завершит рекурсию.

второй ингредиент здесь-частное наследование, которое можно рассматривать как форма композиции. В сочетании с рекурсивным шаблоном вы можете использовать его для создания класса переменных размеров, например вектора определенного измерения.


обратите внимание на это:

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

изменяется первый параметр шаблона. Это уже не тот класс. Шаблон класса не является полным классом, пока не будут указаны все параметры.

действительно, незаконно наследовать один и тот же шаблон класса и передавать один и тот же набор параметров, но здесь это не так.