模板和继承

时间:2013-11-08 13:57:01

标签: c++ templates inheritance

如果我有一个基类及其层次结构:

class BaseClass {
}

class DerivedClass : public BaseClass {
}

一个模板化的课程:

template <class T> struct TemplatedClass {
}

我怎样才能做到这一点? :

// 1:
void doSomething(TemplatedClass<BaseClass *> const &t);

// 2:
std::vector<TemplatedClass<BaseClass *>> v;

TemplatedClass<DerivedClass *> a;

// Doesn't compile
doSomething(a);

// Doesn't compile
v.push_back(a);

2 个答案:

答案 0 :(得分:2)

您的模板化类也可以具有层次结构。但是,您需要指定基数:

template <typename...>
struct TC;

template <>
struct TC<> {
    virtual ~TC() {}
};
template <typename T, typename... B>
struct TC
    : TC<B...> {
    // ...
};

使用继承的可变参数,这应该允许您指定模板之间的关系以模仿底层的继承层次结构。例如:

TC<Base>* d = new TC<Derived, Base>(/*...*/);

答案 1 :(得分:1)

您需要将TemplatedClass<DerivedClass*>转换为TemplatedClass<BaseClass *>,因为它们是独立类型。最好的方法是使用构造函数,如下所示:

template <class T> struct TemplatedClass {
    template<class P> TemplatedClass( const TemplatedClass<P> &an );
};

看起来您正在尝试制作类似智能指针的内容,您应该看看它是如何在std::shared_ptrboost::shared_ptr上完成的。 如果您计划在生产中使用此代码和/或与您的团队共享,您可能需要对传递给此ctor的数据类型进行额外检查:

template <class T> struct TemplatedClass {
    template<class P, class = typename std::enable_if<std::is_convertible<P, T>{}>::type>
    TemplatedClass( const TemplatedClass<P> &an );
};

同样最好的方法是查看shared_ptr的来源,看看它是如何在那里完成的。