https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120917
--- Comment #18 from Frank Heckenbach <f.heckenb...@fh-soft.de> --- (In reply to Frank Heckenbach from comment #17) > Maybe I've found a work-around. I took the is_instance_of_v template from > https://indii.org/blog/is-type-instantiation-of-template/ and turned it into > a concept, so I can replace: > > void f (S <auto>); > void g (T <auto, auto>); > > with: > > void f (instance_of <S> auto); > void g (instance_of <T> auto); > > which at least keeps the required changes localized. > > I think it won't work with "partially auto instantiations" such as: > > void g (T <auto, int>); > > But fortunately I don't have many of them. > > Since I'm not so well versed with concepts yet, can you please confirm > whether this is effectively equivalent? To answer my own question, no it's not. T <auto> also accepts derived types, instance_of does not. So another attempt: #include <type_traits> template < template <typename ...> typename Template, typename ... U> void CheckIsDerivedFromTemplate (const volatile Template <U ...> &); template <typename T, template <typename ...> typename Template> concept DerivedFromTemplate = requires (T v) { CheckIsDerivedFromTemplate <Template> (v); }; template <typename T> struct S { }; struct U: S <int> { }; struct V: U { }; class W: U { }; void f (S <auto>) { } void f_ (DerivedFromTemplate <S> auto) { } int main () { S <double> a; // OK f (a); f_ (a); f (S <int> ()); f_ (S <int> ()); f (V ()); f_ (V ()); // error // f (1); // f_ (1); // f (nullptr); // f_ (nullptr); // f (W ()); // f_ (W ()); } The diagnostics are worse, especially with W, but at least it accepts V and rejects W as it should. So, could this be a viable workaround?