2

我对继承和模板有以下问题:

class Base {};
class Deriv : public Base {};

template <class T> class X{};

void f(X<Base>& inst) {}

int main()
{
  X<Base> xb;
  f(xb);
  X<Deriv> xd;
  f(xd);
  return 0;
}

X<Base>该程序无法编译,因为和之间没有关系X<Deriv>。尽管如此,我认为应该可以X<Base>X<Deriv>. 除了将函数体复制f到新函数之外,我还能做些void g(X<Deriv>& inst)什么吗?

4

5 回答 5

2

您可以继续使用模板:

template<class T>
void f(X<T>& inst) {}

将适用于X<Base>X<Derived>

编译器可能会复制代码(如果它不够聪明),但您不必这样做。

于 2012-04-06T15:52:35.147 回答
1

为什么你认为它们应该是相关的?考虑以下:

template<typename T>
class X;

template<>
class X<Base> {
    int x;
};

template<>
class X<Deriv> {
    double d;
};

它们绝对不能互换。所以不,这些类之间没有关系,你不能将一个传递给期望另一个的函数。你必须做一些事情,比如让这两种类型都继承自另一个公开你需要的接口的通用类型。


关于您的评论,您可以使用类型特征并static_assert执行您在 Java 中会执行的操作:

template<typename T>
void f(X<T>& inst) {
    static_assert(std::is_base_of(Base, T)::value, "Template type must subclass Base");

    // body of function...
}
于 2012-04-06T15:51:07.970 回答
0

如果您需要这样的功能,那么您必须在类型或重载上进行模板化,正如您所说。或者,您可以明确地专门化X这样的X<Derived> : X<Base>.

于 2012-04-06T15:50:02.077 回答
0

这取决于。X考虑is的情况std::shared_ptrstd::shared_ptr<Derived>如果从 派生,它将破坏类型安全std::shared_ptr<Base>,但存在隐式值转换。

However, since you’re passing by reference to non-const, such a value conversion will not help you you directly.

Other possibilities include inheriting from a common interface, and templating your function.

于 2012-04-06T15:54:58.697 回答
0

Different instantiations of a template are unrelated types, even if the instantiating template arguments are related. That is, X<A> is not related to X<B> regardless of what the relationship between A and B might be.

Now as of what can be done, it depends on what your template actually is. In some cases you can provide conversions so that the X<Derived> can be converted to a X<Base> for a particular operation. Another alternative is modifying your function to be able to take any X<T> for which T derives from Base (this can be done by creating a template and using SFINAE to disallow calling it with Ts that don't derive from Base. Again, depending on what your template is, you might be able to offer access to the underlying type, in which case the function could take a reference to Base (consider shared_ptr or unique_ptr with the .get() method)

Without a description of what you actually want to get done it is impossible to provide a good alternative.

于 2012-04-06T15:56:46.343 回答