noexcept 运算符在调用指向成员函数的指针后失败
noexcept operator fails after calling pointer-to-member function
这个 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()));
}
魔杖盒link: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()));
}
f
是 noexcept
,但指向它的指针不是。所以在 g
的定义中,this->*handler()
return 是一个 PMF,它不是 noexcept
(即使你碰巧 return 是 是 noexcept
,所以当你通过写 (this->*handler())()
调用它时,你正在调用一个不是 noexcept
的函数,所以 noexcept
子句有 returns false
.
将 noexcept
添加到第 5 行的末尾即可。
这个 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()));
}
魔杖盒link: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()));
}
f
是 noexcept
,但指向它的指针不是。所以在 g
的定义中,this->*handler()
return 是一个 PMF,它不是 noexcept
(即使你碰巧 return 是 是 noexcept
,所以当你通过写 (this->*handler())()
调用它时,你正在调用一个不是 noexcept
的函数,所以 noexcept
子句有 returns false
.
将 noexcept
添加到第 5 行的末尾即可。