为什么我不能在继承树中static_cast一个模板化对象?

时间:2015-09-28 11:12:01

标签: c++ templates inheritance casting

简短:

  • 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持有人?

1 个答案:

答案 0 :(得分:4)

由于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)编译,该语句就会编译。