使用派生类作为模板构造函数

时间:2015-09-03 11:52:47

标签: c++ templates

我有一个带有模板构造函数的类:

class TCons {
    template <typename T> TCons(T t);
}

专门从事实施:

template <> TCons::TCons(int i) { doMyStuff(i); }

我还有一个基类的专业化:

template <> TCons::Tcons(TBase &t) { doMyStuff(t); }

但是当我尝试使用派生对象作为参数初始化TCons对象时,这似乎不起作用。

class TDeriv: public TBase { };
TDeriv td;
TCons tc = td;

我无法使用指针来解决此问题(因为所有内容都包含在宏中)。问题出现在链接阶段。

这是错的,还是我错过了什么?

1 个答案:

答案 0 :(得分:5)

当我们尝试在此构建tc时:

TCons tc = td;

我们有一个构造函数选择:

template <typename T> TCons(T t);

当我们执行模板扣除时,我们推导出T = TDeriv。这匹配您的TBase显式专业化(也不是int专业化),因此我们坚持使用主要模板。您没有为它提供定义,这就是您遇到链接器错误的原因。

如果您希望在从TBase继承的所有类型上调用TBase构造函数,则必须为这些情况禁用构造函数模板。我们可以用SFINAE做到这一点:

template <typename T,
          typename = std::enable_if_t<!std::is_base_of<TBase, T>::value>>
TCons(T );

同时另外使您的其他构造函数非模板重载:

TCons(int );
TCons(TBase& );

只在需要时专门化 - 重载变得更简单。