调用指向成员函数后,noexcept运算符失败

Jac*_*kie 4 c++ clang noexcept

这个MWE可能看似人为,但失败的static_assert仍然令人惊讶:

#include <utility>

struct C {
  void f() noexcept { }
  using F = void(C::*)();

  static constexpr F handler() noexcept {
    return &C::f;
  }

  void g() noexcept(noexcept((this->*handler())())) {
  }
};

int main() {
  static_assert(noexcept(std::declval<C>().g()));
}
Run Code Online (Sandbox Code Playgroud)

Wandbox链接:https://wandbox.org/permlink/a8HSyfuyX1buGrbZ

我希望这可以用于Clang而不是GCC,因为它们在运算符noexcept的上下文中对"this"的处理方式不同.

Jus*_*tin 7

看到你static_assert没有字符串参数,你正在使用C++ 17.在C++ 17中,noexcept成为类型系统的一部分.这意味着:

using F = void(C::*)();
Run Code Online (Sandbox Code Playgroud)

这个PMF不是noexcept.调用它等同于调用noexcept(false)成员函数.您需要将函数类型标记为noexcept:

using F = void(C::*)() noexcept;
Run Code Online (Sandbox Code Playgroud)

该更改允许您的代码编译:

#include <utility>

struct C {
  void f() noexcept { }
  using F = void(C::*)() noexcept;

  static constexpr F handler() noexcept {
    return &C::f;
  }

  void g() noexcept(noexcept((this->*handler())())) {
  }
};

int main() {
  static_assert(noexcept(std::declval<C>().g()));
}
Run Code Online (Sandbox Code Playgroud)

在Godbolt上