为什么我不能将模板化对象静态化为继承树

Why can I not static_cast a templated object down an inheritance tree?

本文关键字:对象 静态 继承 不能 为什么      更新时间:2023-10-16

简而言之:

  • Derived继承自Base
  • Holder被模板化为包含指向任何内容的指针
  • 我可以看出,一个被称为Holder<Base>的对象是Holder<Derived>

    如何告诉编译器?

这不会编译:

struct Base { };
struct Derived : Base { };
template <typename T>
struct Holder {
    T* point;
    int id;
};
Derived* d = new Derived();
Holder<Base> holder {d, 12};
Holder<Derived> specific( static_cast<Holder<Derived>>(holder) );

error: no matching conversion for static_cast from 'Holder<Base>' to 'Holder<Derived>'

这无疑是一次天真的尝试。但为什么这不起作用,我应该如何获得我需要的specific支架?

因为Holder<Derived>不是从Holder<Base>派生的,所以它们是完全不相关的类型,恰好是从同一个类模板生成的。

您可以创建一个包含正确值的Holder<Derived>

Holder<Derived> specific{ static_cast<Derived*>(holder.point), holder.id };

或者,您可以通过添加一个执行强制转换的转换构造函数将该功能添加到Holder类模板本身:

template <typename T>
struct Holder {
    Holder(T* pt, int id) : point(pt), id(id) { }
    template<typename U>
        Holder(const Holder<U>& h)
        : point(static_cast<T*>(h.point)), id(h.id)
        { }
    T* point;
    int id;
};

现在,您最初尝试使用static_cast将起作用,因为它们之间存在有效的转换,或者您可以将其写成:

Holder<Derived> specific( holder );

只要static_cast<Derived*>(holder.point)编译,该语句就会编译。