Тыц / Possible implementation: зачем нужны оба test_pre_is_base_of()? Сначала не понял про первый, тупо закомментил его – и вроде всё работает. Потом заинлайнил второй – и опять работает:
namespace details {
template <typename B> std::true_type test_pre_ptr_convertible(const volatile B*);
template <typename> std::false_type test_pre_ptr_convertible(const volatile void*);
}
template <typename Base, typename Derived> struct is_base_of : std::integral_constant<
bool,
std::is_class<Base>::value &&
std::is_class<Derived>::value &&
decltype(details::test_pre_ptr_convertible<Base>(static_cast<Derived*>(nullptr)))::value
> {};
class A {};
class B {};
class D : public B {};
static_assert(is_base_of<B, D>::value);
static_assert(!is_base_of<A, D>::value);
static_assert(!is_base_of<int, bool>::value);