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.