如何检测构造函数是否与抛出的析构函数无关

How to detect if a contructor is noexcept with a throwing destructor

本文关键字:析构函数 是否 何检测 检测 构造函数      更新时间:2023-10-16

以下代码将无法在大多数编译器上编译:

#include <type_traits>
class Foo
{
public:
Foo() noexcept {}
~Foo() noexcept(false) {}
};
static_assert(std::is_nothrow_default_constructible_v<Foo>);

CppReference还指出,这在编译器实现中很常见,但没有提供替代方案。如果析构函数不影响结果,我如何测试构造函数是否为noexcept?

正如LWG第2116期中所提到的,从您链接的cppreference页面链接,这不是一个bug,而是预期行为。

正如该问题中所提到的,可以使用非抛出放置new来测试仅构造函数的异常规范:

static_assert(noexcept(::new(std::nothrow) Foo()));

这需要将<new>包括在std::nothrow中。

以下是该特性的粗略实现:

template<class T, class = void>
struct is_nothrow_default_constructible
: std::bool_constant<false> { };
template<class T>
struct is_nothrow_default_constructible<T,
std::enable_if_t<noexcept(::new(std::nothrow) T())>>
: std::bool_constant<true> { };