https://gcc.gnu.org/bugzilla/show_bug.cgi?id=96877
--- Comment #5 from Jonathan Wakely <redi at gcc dot gnu.org> --- (In reply to Ian Henriksen from comment #3) > The goal of doing it that way was get the exception specification onto the > pointer type in C++11 and C++14. The intent was to get the equivalent of > > typedef void(*function_type)(void*) noexcept; > > but with standards earlier than C++17. But you can't do that. There is no difference between void(*)(void*) noexcept and void(*)(void*) in C++14, they're the same type. It doesn't matter whether you write the type out, or do remove_reference_t<decltype(std::declval<T>())>, the type is the same. Concretely, it doesn't work: #include <utility> using function_type = decltype(std::declval<void (*)(void*) noexcept>()); static_assert( noexcept(std::declval<function_type>()(nullptr)), "" ); The assertion fails before C++17, because the type does not have noexcept in it. (In reply to Ian Henriksen from comment #4) > It's worth noting that, with g++ > > using function_type = void (*)(void*) noexcept; > > actually works, You can write that declaration, but the noexcept still isn't part of the type: #include <utility> using function_type = void (*)(void*) noexcept; static_assert( noexcept(std::declval<function_type>()(nullptr)), "" ); If you need C++17 then use C++17.