Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
614 views
in Technique[技术] by (71.8m points)

c++ - Why is the downcast in CRTP defined behaviour

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...