https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88092
--- Comment #4 from Hana Dusíková <hanicka at hanicka dot net> --- (In reply to Emmanuel Le Trong from comment #3) > I have a problem with this. AFAIK, nowhere in the standard is written that a > class template without argument (i.e. not a type!) can be used as the type > of a non-type template argument. [temp.param] §4 says > > > A non-type template-parameter shall have one of the following (optionally > > cv-qualified) types: > > — a type that is literal, has strong structural equality (10.10.1), has no > > mutable or volatile subobjects, and in which if there is a defaulted member > > operator<=>, then it is declared public, > > — an lvalue reference type, > > — a type that contains a placeholder type (9.1.7.5), or > > — a placeholder for a deduced class type (9.1.7.6). > > So > > template <class T> struct A {}; > template <A a> struct B {}; > > should not be valid IMO. You are correct, you must have class template argument deduction rule. This should be valid: template <class T> struct A { constexpr A(...) {} }; template <class T> A(T) -> A<T>; template <A a> struct B {};