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.