【发布时间】:2018-10-30 05:52:42
【问题描述】:
考虑一下这些代码 sn-ps:
版本(1)
void q() {}
class B {
void f() noexcept(noexcept(q())) {q(); }
decltype(&B::f) f2;
};
版本 (2)
void q() {}
class B {
void f() noexcept(true) {q(); }
decltype(&B::f) f2;
};
版本 (3)
void q() {}
class B {
void f() noexcept {q(); }
decltype(&B::f) f2;
};
所有版本的 GCC 编译这些代码 sn-ps 没有任何错误或警告(包括trunk-version)。所有支持 C++17 的 Clang 版本都拒绝版本(1)和(2),但不支持版本(3),并出现以下错误:
<source>:4:16: error: exception specification is not available until end of class definition
decltype(&B::f) f2;
^
考虑到标准将noexcept 定义为等同于noexcept(true) [except.spec]。因此,版本(2)和版本(3)应该是等价的,它们不适用于clang。
因此,以下问题:在什么时候需要根据 C++17 标准评估异常规范?而且,如果上面的某些代码无效,那么背后的原因是什么?
有兴趣的人的抽象背景:
template <typename F>
struct result_type;
template<typename R, typename C, typename... Args>
struct result_type<R(C::*)(Args...)> {
using type = R;
}; // there may be other specializations ...
class B {
int f() noexcept(false) { return 3; }
typename result_type<decltype(&B::f)>::type a;
};
此代码至少应在 C++ 14 之前有效,因为 noexcept 不是函数类型的一部分(对于 clang,它编译到版本 3.9.1)。对于 C++ 17,没有办法这样做。
【问题讨论】:
-
您是否尝试过完全限定
q:noexcept(noexcept(::q()))? -
这没有影响。你甚至可以写
noexcept(true)。即,只要 noexcept 包含表达式并且不仅仅是noexcept,clang 就拒绝编译。如果这符合标准,我会感到惊讶,但我找不到来源。
标签: c++ language-lawyer c++17 noexcept