继承类型的指针之间的静态转换

Mad*_*den 1 c++ inheritance casting static-cast

我想这样做

static_cast<IntrusivePtr<B>>(IntrusivePtr<A>)
Run Code Online (Sandbox Code Playgroud)

其中B公开来自A但是这给出了错误

invalid conversion from A* to B*
Run Code Online (Sandbox Code Playgroud)

任何人都可以向我解释这里的问题吗?我可以通过这样做来解决它

static_cast<B*>(IntrusivePtr<A>.get())
Run Code Online (Sandbox Code Playgroud)

理论上这正是上述错误消息所说的内容是不允许的.这是GCC 4.4.7

Bar*_*rry 6

您正在寻找的概念称为类型协方差 - 您希望IntrusivePtr<T>协变T,这意味着它IntrusivePtr<D>IntrusivePtr<B>if D的子类型的子类型B.有类型系统支持的语言,C++不是其中之一.

在C++中,IntrusivePtr<A>并且IntrusivePtr<B>是完全不相关的类型,不管是什么AB不是(除非它们是相同的类型).如果您想支持该转换,则必须明确支持:

template <class T>
struct IntrusivePtr {
    template <class U, class = std::enable_if_t<std::is_convertible<U*, T*>::value>>
    IntrusivePtr(IntrusivePtr<U> const& rhs) { ... }
};
Run Code Online (Sandbox Code Playgroud)

或者做你正在做的事情,并在IntrusivePtr课堂模板上做一步.


在重读时的问题回想起来,似乎更可能是IntrusivePtr支持上述转换,但确实这两种类型之间的隐式转换-这是有效的衍生-底部但基本以衍生无效.但是你总是可以从base-to-derived明确地转换.那是:

struct B { };
struct D : B { };

B b;
D* d1 = &b;                  // error
D* d2 = static_cast<D*>(&b); // ok
Run Code Online (Sandbox Code Playgroud)