为什么 CRTP 中的沮丧定义行为

Why is the downcast in CRTP defined behaviour

我使用 CRTP 模式有一段时间了,但是阅读有关与向下转换相关的未定义行为的答案我不明白为什么 static_cast<Derived&>(this),其中 this 是 [=14= 类型] 是定义的行为,其中 Derived 公开继承自 Base<Derived>.

标准很明确:

static_cast < new_type > ( expression )

If new_type is a pointer or reference to some class D and the type of expression is a pointer or reference to its non-virtual base B, static_cast performs a downcast. This downcast is ill-formed if B is ambiguous, inaccessible, or virtual base (or a base of a virtual base) of D.

但是看类似的问题,C++ inheritance downcasting:

How do I cast from a point object [Base class] to a subpoint object [Derived class]?

评分最高的答案:

"You can't; unless either point [Base] has a conversion operator, or subpoint [Derived] has a conversion constructor, in which case the object types can be converted with no need for a cast."

另一个例子:static_cast parent class to child class C++

// B : public A
A a;
B* bptr = static_cast<B*>(&a);

评分最高的评论:

"It's undefined behavior."

然后说:

"You can do it safely using either CRTP or dynamic_cast."

这里()又提到了:

Base base{190};
A& a = static_cast<A&>(base);

"No [it is not valid], an object of type Base is not an object of type A [Derived]"


在 CRTP 中执行向下转换有何不同;为什么它不会导致未定义的行为,但上述情况会导致?按照上面答案的逻辑,说 class Base<Derived> 不是 Derived 类型的对象是不是真的(反之亦然),但您可以使用 static_cast?

也许我只是误解了 CRTP。

回顾第一段:

If new_type is a pointer or reference to some class D and the type of expression is a pointer or reference to its non-virtual base B, static_cast performs a downcast. This downcast is ill-formed if B is ambiguous, inaccessible, or virtual base (or a base of a virtual base) of D.

并包括下一句:

Such static_cast makes no runtime checks to ensure that the object's runtime type is actually D, and may only be used safely if this precondition is guaranteed by other means, such as when implementing static polymorphism.

CRTP uses/is 静态多态性的别称。

给定 struct D : B<D> 如果 B<D> static_cast*thisD&,那么这是定义的行为,因为 this 指针确实是指向 DB<D> 的指针。