3

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


更令人困惑的是,当我从https://wandbox.org/permlink/JUI3rsLjKRoPArAl中删除一种方法的 noexcept 说明符时,所有 noexcept 值都会发生变化,如此处所示https://wandbox.org/permlink/yBJ0R4PxzAXg09ef。当一个是 noexcept 时,所有都是 noexcept。如何?这是一个错误吗?

4

1 回答 1

6

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

在你问的评论中:

此外,自 c++17 以来 mem_fn 的声明没有 noexcept 重载,那么它如何从用户那里检测到这些信息?

它不需要有一个 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) );

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

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

于 2017-10-17T11:01:30.323 回答