Search code examples
c++metaprogrammingtemplate-meta-programming

Why don't types with invalid inheritance get rejected when passed as template parameters?


As we all know, classes can't be inherited from fundamental types and from classes that are marked as final. But despite that, the code presented below compiles without any problems on Clang 12 and GCC 9.

#include <type_traits>

template<typename T>
struct Inheriter : public T{};

int main()
{
    std::void_t<Inheriter<int>>();
}

Solution

  • There will only be an error due to the inheritance if the template specialization Inheriter<int> is instantiated.

    Simply using the specialization, e.g. as a template argument, does not cause implicit instantiation. Roughly speaking implicit instantiation of the class template specialization happens only if it is used in a context that requires the class to be complete or otherwise depends on class completeness.

    std::void_t is defined as

    template<typename...>
    using void_t = void;
    

    There is nothing in this alias template that requires the template argument to be a complete type. As a consequence no implicit instantiation will happen.

    The program is therefore well-formed and the compiler should not reject it.