повторное объявление параметра шаблона

Это то, чего я хочу достичь. Компонент leaf наследует Component<ParentT>, другие будут наследовать Component<ParentT, ChildT>

template <typename T>
class Component{
  protected:
    typedef Component<T> ParentComponentT;
  ...
};

template <typename ParentT, typename ChildT>
class Component: public Component<ParentT>{
  protected:
    typedef std::vector<ChildT*> CollectionT;
  ...
};

но проблема в том, что параметры шаблона объявляются повторно. и я не могу переместить второй выше первого, потому что второй наследует первый.

error: redeclared с 2 параметрами шаблона(ов)
Примечание: предыдущее объявление "компонент класса шаблона" использовало 1 параметр(ы) шаблона

1 ответов


это компилируется и насколько я понимаю, делает то, что вам нравится:

#include <vector>

class NoneT {};

template <typename ParentT,typename ChildT=NoneT>
class Component: public Component<ParentT>{
  protected:
    typedef std::vector<ChildT*> CollectionT;
};

специализации NoneT:

template<>
template<typename T>
class Component<T,NoneT>{
protected:
   typedef Component<T> ParentComponentT;
};

int main(){
   typedef Component<double> someT;
   typedef Component<double,int> someT2;
   typedef Component<double,void> someT3;
}

someT будет ParentComponentT и someT2 будет CollectionT.

EDIT:

ответ на комментарий/вопрос ниже: typename ChildT=noneT означает, что по умолчанию ChildT будет noneT. Итак, если второй аргумент шаблона не задан noneT тип будет использоваться.

специализация затем определяет содержимое класса для версии с одним аргументом.

EDIT2:

поскольку я знаю из чата, что вы используете компонент в качестве базового класса, я предлагаю вместо чего-то вроде

class myclass: public Component<Section, Line>

вы можете использовать множественное наследование

class myclass: public ParentComponent<Section>, CollectionComponent<Line>

С

template <typename T>
class ParentComponent{
  protected:
    typedef Component<T> ParentComponentT;
};

template <typename ChildT>
class CollectionComponent {
  protected:
    typedef std::vector<ChildT*> CollectionT;
};