c++ - noexcept 运算符在调用指向成员函数的指针后失败

标签 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()));
}

魔杖链接:https://wandbox.org/permlink/a8HSyfuyX1buGrbZ

我希望这适用于 Clang 但不适用于 GCC,因为它们在运算符 noexcept 的上下文中对“this”的处理方式不同。

最佳答案

鉴于您的 static_assert 没有字符串参数,您使用的是 C++17。在 C++17 中,noexcept 成为类型系统的一部分。这意味着给定:

using F = void(C::*)();

这个 PMF 不是noexcept。调用它相当于调用一个noexcept(false)成员函数。您需要将函数类型标记为noexcept:

using F = void(C::*)() noexcept;

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

#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()));
}

On Godbolt

关于c++ - noexcept 运算符在调用指向成员函数的指针后失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46719806/

相关文章:

c++ - 如何在类 noexcept 之外定义默认构造函数?

c++ - 我什么时候应该真正使用 noexcept?

c++ - cout 不命名类型

c++ - 使用 clang 对 std::atomic 函数的调用不明确

objective-c - 如何在 Xcode 中更改 MyFramework_vers.c 的编译标志?

c++ - 删除析构函数的类被认为是可简单复制的?

c++ - 媒体基金会 : Cannot change a FPS on webcam

c++ - 错误 : expected unqualified-id before 'for' . 编译因 -Wfatal-errors 而终止

C++ 在整数表达式中使用 AND 运算符

c++ - 为什么 "dynamic exception"保证会导致开销?