【问题标题】:template parameter redeclaration模板参数重新声明
【发布时间】:2012-08-05 06:25:22
【问题描述】:

这就是我想要实现的。叶组件会继承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;
  ...
};

但问题是模板参数被重新声明。而且我不能将第二个移到第一个之上,因为第二个继承了第一个。

错误:使用 2 个模板参数重新声明
注意:之前的声明“模板类组件”使用了 1 个模板参数

【问题讨论】:

  • 暂时忽略可变参数模板,模板有固定数量的参数;单个Component&lt;&gt; 不能同时具有一个和两个参数。这看起来很像XY problem——你实际上想要完成什么?
  • 那么建模的好方法是什么? Component &lt;T, void&gt; ?
  • 这取决于 - 为什么你希望 base 和 child 具有相同的名称?给他们不同的类型名称,你没有问题。
  • 是的,差不多(虽然如果你说为什么你不想给他们不同的名字可能会有所帮助,这会有所帮助;再次,XY问题)。跨度>
  • @Johan :我从来没有说过——你仍然有两个模板参数,不管你是否指定两者。

标签: c++ templates


【解决方案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 将具有 ParentComponentTsomeT2 将具有 CollectionT

编辑:

回答下面的评论/问题:typename ChildT=noneT 表示默认的ChildT 将是noneT。因此,如果没有给出第二个模板参数,则将使用 noneT 类型。

然后,特化定义该单参数版本的类内容。

EDIT2:

因为我从聊天中知道您使用 Component 作为基类,所以我建议不要使用类似的东西

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

【讨论】:

  • 如果是第一个模板,为什么要使用ChildT=NoteTChildT=void?你在第二个模板上专门处理它
  • 如果没有给出第二个模板参数,它将转到模板的第二个版本。为什么会寻找默认参数?
  • 这就是语言的工作原理。第二个参数有一个默认参数,并且始终有效。专业化决定了该特定类型会发生什么。
  • 我的编译是void 为什么要使用NoneT
  • Neel Basu,是的,这行得通,但是如果您真的想使用 void 类型作为第二个参数,那会使您的课程失败。从您发布的代码来看,这并非不可能。
猜你喜欢
  • 1970-01-01
  • 2020-08-17
  • 1970-01-01
  • 2017-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-21
  • 1970-01-01
相关资源
最近更新 更多