如何检测构造函数是否为抛出析构函数的 noexcept
How to detect if a contructor is noexcept with a throwing destructor
以下代码将无法在大多数编译器上编译:
#include <type_traits>
class Foo
{
public:
Foo() noexcept {}
~Foo() noexcept(false) {}
};
static_assert(std::is_nothrow_default_constructible_v<Foo>);
CppReference 还 states 这在编译器实现中很常见,但没有提供替代方案。如何在析构函数不影响结果的情况下测试构造函数是否为 noexcept?
如 LWG issue 2116 中所述,链接自您链接的 cppreference 页面,这不是错误,而是预期的行为。
那个issue也提到,可以使用非抛出的placement-new,只构造对象,不析构对象,只测试构造函数的异常规范:
static_assert(noexcept(::new(std::nothrow) Foo()));
这需要为 std::nothrow
添加 <new>
。
这里是 trait 的粗略实现:
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> { };
以下代码将无法在大多数编译器上编译:
#include <type_traits>
class Foo
{
public:
Foo() noexcept {}
~Foo() noexcept(false) {}
};
static_assert(std::is_nothrow_default_constructible_v<Foo>);
CppReference 还 states 这在编译器实现中很常见,但没有提供替代方案。如何在析构函数不影响结果的情况下测试构造函数是否为 noexcept?
如 LWG issue 2116 中所述,链接自您链接的 cppreference 页面,这不是错误,而是预期的行为。
那个issue也提到,可以使用非抛出的placement-new,只构造对象,不析构对象,只测试构造函数的异常规范:
static_assert(noexcept(::new(std::nothrow) Foo()));
这需要为 std::nothrow
添加 <new>
。
这里是 trait 的粗略实现:
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> { };