Consider following code:
#include <type_traits>
struct T {};
static_assert(std::is_trivially_destructible< T >{});
static_assert(std::is_trivially_default_constructible< T >{});
struct N { ~N() { ; } };
static_assert(!std::is_trivially_destructible< N >{});
static_assert(!std::is_trivially_default_constructible< N >{});
It compiles fine using clang 3.7.0
: live example. But summarizing the Standard:
The default constructor for class T is trivial (i.e. performs no action) if all of the following is true:
- The constructor is not user-provided (i.e., is implicitly-defined or defaulted)
- T has no virtual member functions
- T has no virtual base classes
- T has no non-static members with default initializers. (since C++11)
- Every direct base of T has a trivial default constructor
- Every non-static member of class type has a trivial default constructor
As I can see there is no dependence on triviality of the destructor.
I missed something? Is it clang
bug?
ADDITIONAL
I found a workaround: is static_assert(__has_trivial_constructor( N ));
built-in type trait. There is support in clang
, gcc
and MSVC
.
For is_noexcept_constructible
family of type traits there is workaround too.
This issue is covered in LWG issue 2116: std::swap noexcept(what?), we can see this from the cppreference section for std::is_trivially_default_constructible:
which deceptively only talks about
is_nothrow_default_constructible
but if we read the issue in detail we see it also applies here as well.Perhaps is is easier if we follow the gcc bug report: [DR 2116] has_nothrow_.*constructor bugs referenced first which says:
this explicitly says what is only really alluded to in the LWG issue which eventually says:
which also effects
std::is_trivially_default_constructible
which relies on std::is_trivially_constructible which does the same asis_constructible
but has the further restriction that: