这个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()));
}
Wandbox链接:https://wandbox.org/permlink/a8HSyfuyX1buGrbZ
我希望这可以用于Clang而不是GCC,因为他们对&#34;这个&#34;在运算符noexcept的上下文中。
答案 0 :(得分:7)
看到你的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()));
}
答案 1 :(得分:3)
f
是noexcept
,但指向它的指针不是。因此,在g
的定义中,this->*handler()
返回的PMF不是noexcept
(即使您碰巧返回了 {{{ 1}},所以当您通过编写noexcept
来调用它时,您调用的函数不是(this->*handler())()
,因此noexcept
子句返回noexcept
。
将false
添加到第5行的末尾,然后就可以了。