为什么编译器会抱怨我的 dynamic_cast?

Why does the compiler complain about my dynamic_cast?

我正在尝试找出我的代码中出现编译错误的原因:

class A
{
    public:
    virtual ~A(){}
};

class B: public A
{
    public:
    virtual ~B(){}
};

class D: public B
{
    public:
    virtual ~D(){}
};

template <class X, class Y>
X* fun(X* p){return dynamic_cast<Y*>(p);}

int main()
{
    A* q = dynamic_cast<B*>(new D());
    A* p = fun<D,B>(new D());
}

对我来说,指针 q 和 p 似乎应该指向相同的类型,但是对于 p,我收到一个编译器错误 "invalid conversion from ‘B*’ to ‘D*’"。我唯一没有收到错误的时间是当我以 B 是 D 的子类的方式更改 类 时(因此 p 是空指针)。谁能帮我理解为什么会这样?

I don't get the problem, so the last line of code will be returning a D*, but since D is a subclass of A that should be OK, right?

不,这不行。 D 开始子类 A 无关紧要。

Can anyone help me understand why this happens?

指向基址的指针(B*Y*)不能隐式转换为指向派生的指针(D*X*)。

另一方面,A* p = fun<B,D>(new D()); 将是合式的。注意模板参数的不同顺序。然而另一方面,fun 并不是很有用的函数。

template <class X, class Y>
X* fun(X* p){return dynamic_cast<Y*>(p);}

这个函数需要一个 X* 和 returns 一个 X*

在正文中,您将其转换为 Y*。然后您尝试将其隐式转换为 X*.

您遇到的错误是在 fun 的正文中,您将 D* 转换为 B*,然后尝试将其隐式转换为 D* 再一次。那失败了。因此你的错误。

查看编译器错误时,它有助于

  1. 每条语句各占一行。如果语句很复杂,将其分解成多个语句。

  2. 查看编译器提示错误的那一行。

修复方法是:

template <class X, class Y>
Y* fun(X* p){return dynamic_cast<Y*>(p);}

现在您的代码可以工作了。