https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92320
Bug ID: 92320 Summary: Constexpr function pointer derived from lambda is not accepted as template parameter Product: gcc Version: 9.2.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: jleahy+gcc at gmail dot com Target Milestone: --- The following code is not accepted by the compiler, whereas I believe it is well-formed according to the standard: template<auto V> void templ() {} void foo() { constexpr auto * a = +[](){}; templ<a>(); } Here is a less condensed version that demonstrates a number of similar circumstances: (only the very last case is rejected by GCC) template<auto V> void templ() {} void dummy(){} void foo() { constexpr int a = 7 + 3; templ<a>(); templ<dummy>(); typedef void(FPtr)(); constexpr FPtr * b = &dummy; templ<b>(); constexpr FPtr * c = [](){}; templ<c>(); } Generally speaking it seems that GCC is perfectly happy instantiating a template with a constexpr (as you would hope) and with a constexpr function pointer even, but only if that function pointer derives from a free function. If a constexpr function pointer derives from the constexpr conversion of a lambda to a function pointer than GCC rejects the code with an error like the below: error: 'foo()::<lambda()>::_FUN' is not a valid template argument for type 'void (*)()' because 'static constexpr void foo()::<lambda()>::_FUN()' has no linkage This code is accepted by clang.