https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90664

            Bug ID: 90664
           Summary: noexcept confuses template argument deduction
           Product: gcc
           Version: 9.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: ofv at wanadoo dot es
  Target Milestone: ---

consider this code:

<<<<<<<<<<<<<<<<<<

template <typename TT, typename MFP, MFP> struct OpM;

template <typename TR, typename TT, TR (TT::*f)()>
struct OpM<TT, TR (TT::*)(), f>
{};

class Class {
public:
  int address() noexcept { return 0; }
  void address(int) noexcept {}
};

struct Sk {
  template <class C, typename R> Sk(R (C::*p)()) {
    typedef OpM<C, R (C::*)() /* noexcept */, &Class::address> OP;
  }
};

Sk sk(static_cast<int (Class::*)()>(&Class::address));

>>>>>>>>>>>>>>>>>>>>>>>>

$ g++.exe -std=c++17 -fsyntax-only -c kk.cpp
kk.cpp: In instantiation of 'Sk::Sk(R (C::*)()) [with C = Class; R = int]':
kk.cpp:19:53:   required from here
kk.cpp:15:64: error: 'int (Class::*)(){((int (Class::*)())Class::address), 0}'
is not a valid template argument for type 'int (Class::*)()'
   15 |     typedef OpM<C, R (C::*)() /* noexcept */, &Class::address> OP;
      |                                                                ^~
kk.cpp:15:64: note: it must be a pointer-to-member of the form '&X::Y'


The error message is obviously wrong.

Also, I suppose that noexcept is leaking. The static_cast has no problem
deducing the correct overload without mentioning noexcept but then the
instantiation of Sk in the typedef fails because noexcept is missing
(unconmment the noexcept and the compilation succeeds).

The problem was first noticed with gcc 8.x and boost 1.70.

Reply via email to