With gcc 7.1.0 std::mem_fn
is able to detect noexcept-ness on a member function pointer. How does it do this? I thought the noexcept
specifier was not a part of the function type?
What is even more confusing is when I remove the noexcept specifier on one method from https://wandbox.org/permlink/JUI3rsLjKRoPArAl all the noexcept values change as seen here https://wandbox.org/permlink/yBJ0R4PxzAXg09ef. And when one is noexcept, all are noexcept. How? Is this a bug?
The behaviour you're seeing with GCC in C++14 mode is a bug, see https://gcc.gnu.org/PR77369
In the comments you ask:
Also the declaration of mem_fn since c++17 does not have a noexcept overload, then how does it detect this information from the user?
It doesn't need to have a noexcept overload, consider this C++17 code:
template<typename T>
constexpr bool is_noexcept_callable(T t) {
return noexcept(t());
}
void f() noexcept { }
void g() { }
static_assert( is_noexcept_callable(f) );
static_assert( !is_noexcept_callable(g) );
There's no need to have a noexcept overload of is_noexcept_callable
because in C++17 the exception-specification is part of the type, so all the information is already encoded in the type T
. When you instantiate std::mem_fn
with a pointer to a noexcept(true)
function it knows that invoking that function can't throw. When you instantiate it with a noexcept(false)
function it knows it might throw.
Finally, the reason your example doesn't compile in C++17 mode with GCC 7.1 is https://gcc.gnu.org/PR80478 which is fixed in GCC 7.2 (so upgrade your compiler).