The following code will fail to compile on most compilers:
#include <type_traits>
class Foo
{
public:
Foo() noexcept {}
~Foo() noexcept(false) {}
};
static_assert(std::is_nothrow_default_constructible_v<Foo>);
CppReference also states that this is common in compiler implementations, but provides no alternative. How can I test if a constructor is noexcept without the destructor influencing the result?
As mentioned in LWG issue 2116, linked from the cppreference page you linked, this is not a bug, but intended behavior.
As also mentioned in that issue, one can use the non-throwing placement-new, which only constructs, but doesn't destruct an object, to test the exception specification of only the constructor:
static_assert(noexcept(::new(std::nothrow) Foo()));
This requires including <new>
for std::nothrow
.
Here is a rough implementation of the 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> { };