noexcept操作的调用指针到成员函数
问题描述:
这MWE可能会出现人为后会失败,但失败的static_assert是令人惊讶的仍然:noexcept操作的调用指针到成员函数
#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
我希望它可以工作在锵但不是GCC由于其不同的治疗方法“这个”在运营商noexcept的情况下。
答
鉴于你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()));
}
答
f
为noexcept
,但指针是不。所以在g
定义,this->*handler()
返回PMF这是不noexcept
(即使你碰巧返回MF的地址是noexcept
,所以当你调用写(this->*handler())()
那么你调用一个函数,而不是noexcept
,所以noexcept
条款有返回false
。
添加noexcept
至5行的结束,它的工作原理。
什么是你的问题? – aschepler
如果其中一个答案回答你的问题,你能接受它。如果两人都没有回答你的问题,你能解释一下为什么这么说,我们可以提高我们的答案? – Justin
很抱歉,很长的延迟;我对答案不满意,但我会接受一个答案,因为他们回答了这个问题。但是,在我的情况下,“f”是库的用户传递的模板参数,所以我需要查询函数类型的noexcept-ness以正确地声明指向成员函数的noexcept说明符。不幸的是,即使我添加noexcept到类型别名,它也不会编译,因为我的F别名是模板化的,这会导致内部编译器错误。我会发布关于这个的Clang bug。 – Jackie