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

Time:04-05

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>>();
}

CodePudding user response:

Per [expr.type.conv]:

If the initializer is a parenthesized single expression, the type conversion expression is equivalent to the corresponding cast expression. Otherwise, if the type is cv void and the initializer is () or {} (after pack expansion, if any), the expression is a prvalue of type void that performs no initialization

Meaning T() when T is void (as in your case) is a no-op, and void_t is defined as (per [temp.alias])

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

Meaning that if a valid type is supplied, then it will always become void.

Here's my take:

The code is syntactically correct, and if type substitution succeeds it is provably a no-op. Per the as-if rule, the compiler can prove that the program without this line altogether has identical runtime behavior, and therefore it is safe to ignore it completely. I can reproduce this behavior in MSVC, GCC, and Clang.

CodePudding user response:

The compiler requires that the code be free of syntactic errors. And the sample snippet doesn't have any. Only when you create an Inheriter object can the compiler raise any errors (such as the ones you are expecting)

  • Related