Search code examples
c++templatesstdmetaprogramming

“is_base_of” inside a class declaration


I was having an issue with std::is_base_of being called inside of a class declaration for an incomplete type. I came across this StackOverflow question: Why can't "is_base_of" be used inside a class declaration (incomplete type)?

Then I tried to implement my own metafunction for checking if the given template class is base of another.

I have tested my code with C++17 on MSVC 19.28.29337 (version reported by cl.exe) and on clang-7 online compiler, and seems it works perfectly both for complete and incomplete classes. Here is my code:

namespace helper {
    template<class Base>
    static std::true_type isBaseOf(Base *b);

    template<class Base>
    static std::false_type isBaseOf(...);

    template<class Base>
    static std::false_type isBaseOf(void*);
}

template<class B, class D>
using IsBaseOf = decltype(helper::isBaseOf<B>(std::declval<D*>()));

template<class B, class D>
static inline constexpr bool IsBaseOf_v = IsBaseOf<B, D>::value;

Now I am wondering, what is wrong with my code? Isn't it portable? Doesn't it conform to the standard? Have I done something unacceptable?

Also, if everything is ok with my code, then why is the standard not using such a simple implementation?

Edited

Added handling for void type - thanks to Scheff.


Solution

  • Seems the only difference is that it does not handle non-public inheritance.
    Thanks to Axalo for the comment