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.

Reply via email to