考虑此课程T
struct T{
T() noexcept (true) {}
T(T&& ) noexcept (true) {}
T(const T& ) noexcept (true) {}
T& operator = (T&&) noexcept(true) { return *this; }
T& operator = (const T&) noexcept(true) { return *this; }
~T() noexcept(false) {}
};
考虑这个简单的测试程序:
int main(){
constexpr bool default_ctor = noexcept(T());
static_assert(default_ctor == true, "Default Constructor can throw exceptions");
constexpr bool move_ctor = noexcept(T(std::declval<T>())); //Move ctor
static_assert(move_ctor == true, "Move Constructor can throw exceptions");
constexpr bool copy_ctor = noexcept(T(std::declval<T&>())); //Copy ctor
static_assert(copy_ctor == true, "Copy Constructor can throw exceptions");
constexpr bool move_assign = noexcept(std::declval<T>() = std::declval<T>());
static_assert(move_ctor == true, "Move Assignment can throw exceptions");
constexpr bool copy_assign = noexcept(std::declval<T&>() = std::declval<const T&>());
static_assert(copy_ctor == true, "Copy Assignment can throw exceptions");
//It doesn't matter when using *`type_traits`* either. Same behavior:
constexpr bool no_throw_cons = std::is_nothrow_constructible<T>::value;
static_assert(no_throw_cons == true, "Default Constructor isn't nothrow");
//...others skipped for brevity
}
这里的每一个static_assert
都会被触发。这不应该符合我对标准的理解:
但是,当你声明T
的析构函数没有异常规范(在这个简单的上下文中与noexcept(true)
相同)时,所有断言都会传递!
但是,运行时遵循规范:
struct T{
T() noexcept (true) { throw int(8); }
//.... there rest omitted for brevity
~T() noexcept(false) {}
};
int main(){
T a;
(void)a;
};
按预期调用 std::terminate
。
C ++标准的任何部分是否定义或暗示了这种行为?析构函数上的noexcept (false)
指定者仅在编译时覆盖每个特殊成员函数的异常规范?
或者这是每个主要编译器中的前端错误。
答案 0 :(得分:2)