In the GCC C++20 concepts lib, it has
template<typename _Derived, typename _Base>
concept derived_from = __is_base_of(_Base, _Derived)
&& is_convertible_v<const volatile _Derived*, const volatile _Base*>;
__is_base_of(_Base, _Derived)
not enough?const volatile
in the test?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 ifBase
is a class type that is eitherDerived
or a public and unambiguous base ofDerived
, ignoring cv-qualifiers.Note that this behaviour is different to
std::is_base_of
whenBase
is a private or protected base ofDerived
.
__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.
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.
const volatile
is needed because the traits is supposed to ignore cv-qualifiers. A pointer to T
implicitly converts to pointer to const volatile T
, while to opposite is not true.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With