`std::mem_fn` 如何检测 gcc 7.1.0 中的异常情况

How does `std::mem_fn` detect noexceptness in gcc 7.1.0

在 gcc 7.1.0 中 std::mem_fn 能够检测成员函数指针上的 noexcept-ness。它是怎么做到的?我认为 noexcept 说明符不是函数类型的一部分?


更令人困惑的是,当我从 https://wandbox.org/permlink/JUI3rsLjKRoPArAl all the noexcept values change as seen here https://wandbox.org/permlink/yBJ0R4PxzAXg09ef 的一个方法上删除 noexcept 说明符时。当一个是 noexcept 时,所有都是 noexcept。如何?这是一个错误吗?

您在 C++14 模式下看到的 GCC 行为是一个错误,请参阅 https://gcc.gnu.org/PR77369

在你问的评论中:

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?

它不需要有 noexcept 重载,考虑这个 C++17 代码:

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) );

不需要 is_noexcept_callable 的 noexcept 重载,因为在 C++17 中,异常规范是类型的一部分,所以所有信息都已经编码在类型 T 中.当您使用指向 noexcept(true) 函数的指针实例化 std::mem_fn 时,它知道调用该函数不会抛出。当您使用 noexcept(false) 函数实例化它时,它知道它可能会抛出。

最后,您的示例无法使用 GCC 7.1 在 C++17 模式下编译的原因是 https://gcc.gnu.org/PR80478,它已在 GCC 7.2 中修复(因此请升级您的编译器)。