Noexcept statement does not work after calling a member-pointer function

This MWE may seem far-fetched, but the failed static_assert is nonetheless surprising:

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

Wandbox Link: https://wandbox.org/permlink/a8HSyfuyX1buGrbZ

I would expect this to work on Clang, but not GCC due to their various "this" handling in the context of the noexcept statement.

+4
source share
2 answers

Seeing that yours static_assertdoes not have a string argument, you use C ++ 17. In C ++ 17, it has noexceptbecome part of the type system. This means that this:

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

This PMF is not noexcept. Calling this is equivalent to calling the noexcept(false)member function . You should mark the type of function as 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()));
}

Godbolt

+7

f noexcept, . , g, this->*handler() PMF, noexcept ( MF, noexcept, , (this->*handler())(), , noexcept, noexcept false.

noexcept 5, .

+3

Source: https://habr.com/ru/post/1687399/


All Articles