This MWE may appear contrived, but the failing static_assert is surprising nonetheless:
#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 different treatments of "this" in the context of operator noexcept.
Seeing as your static_assert
has no string argument, you are using C++17. In C++17, noexcept
became part of the type system. What this means is that given:
using F = void(C::*)();
This PMF is not noexcept
. Calling it is equivalent to calling a noexcept(false)
member function. You need to mark the function type as noexcept
:
using F = void(C::*)() noexcept;
That change allows your code to compile:
#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
f
is noexcept
, but the pointer to it is not. So in the definition of g
, this->*handler()
returns a PMF which is not noexcept
(even though you happen to return the address of a MF that is noexcept
, so when you call that by writing (this->*handler())()
then you are calling a function which is not noexcept
, so the noexcept
clause there returns false
.
Add noexcept
to the end of line 5 and it works.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With