The behavior of std::derived_from
is specified in terms of unambiguous public inheritance
The concept derived_from<Derived, Base>
is satisfied if and only if
Base
is a class type that is either Derived
or a public and
unambiguous base of Derived
, ignoring cv-qualifiers.
Note that this behaviour is different to std::is_base_of
when Base
is a private or protected base of Derived
.
__is_base_of
is the compiler intrinsic that is used to implement std::is_base_of
. So using it alone would not produce the desired behavior.
So to check the "unambiguous public" part of the requirement, we may check if a pointer to a derived object is implicitly convertible into a pointer to a base object. That's just standard procedure with C++ classes. The pointers are convertible if the classes model an "is-a" relationship, public inheritance and not from multiple bases.
The const volatile
addition is to handle the requirement of "ignoring cv-qualifiers". By always adding them, the conversion is legal even if for example _Derived
is B const
to some A
(non-const) _Base
. Comparing the pointers as-is would try to convert B const*
to A*
, and would fail on account of discarded cv-qualifiers.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…