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.

Reply via email to