Why is the downcast in CRTP defined behaviour

安稳与你 提交于 2020-01-06 04:46:09

问题


I have used the CRTP pattern for a while, however reading answers about undefined behaviour related to downcasting I don't understand why the static_cast<Derived&>(this), where this is of type Base<Derived>* is defined behaviour, where Derived inherits publicly from Base<Derived>.

The standard is quite clear:

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.

But looking at similar questions, C++ inheritance downcasting:

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

Top rated answer:

"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."

Another example: static_cast parent class to child class C++

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

Top rated comment:

"It's undefined behavior."

But then says:

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

Here (C++ static_cast downcast validity) it is again mentioned:

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]"


How is the downcast performed in CRTP different; why does it not cause undefined behaviour but the cases above do? Following the logic of the answer above, is it not true to say that class Base<Derived> is not an object of type Derived (the converse it true), yet you can use static_cast?

Perhaps I'm simply misunderstanding CRTP.


回答1:


Revisiting the first paragraph:

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.

and including the next sentence:

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 another name for static polymorphism.

Given struct D : B<D> if B<D> static_cast's *this to D&, then this is defined behaviour because the this pointer really is a pointer to both a D and a B<D>.



来源:https://stackoverflow.com/questions/54758272/why-is-the-downcast-in-crtp-defined-behaviour

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!