https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104802
Bug ID: 104802 Summary: Non-type template parameter of reference type disallowed under certain conditions Product: gcc Version: 11.2.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: sneves at dei dot uc.pt Target Milestone: --- Minimal (C++17 and 20) example: template<auto const& ... Args> struct S { template<typename=void> void operator()() const {} }; struct weird_ { int operator&() const { return 123; } } const weird {}; auto f() { S<weird> s {}; s(); } This fails with the error: error: '&(const weird_&)weird.weird_::operator&()' is not a valid template argument of type 'const weird_&' because '(const weird_&)weird.weird_::operator&()' is not a variable Now, if either one of - template<typename=void> is commented out, i.e., the called function is no longer a template; - `weird` has the `operator&` removed; The code compiles without any issues. As far as I can tell this example is not violating any of the constraints the standard puts on lvalue reference parameters, and both Clang and MSVC accept it.