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 ifBaseis a class type that is eitherDerivedor a public and unambiguous base ofDerived, ignoring cv-qualifiers.Note that this behaviour is different to
std::is_base_ofwhenBaseis 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