Per [dcl.fct.def.default]/5:
[...] A function is user-provided if it is user-declared and not explicitly
defaulted or deleted on its first declaration. [...]
Therefore, given
struct HasUserDefinedDestructor {
~HasUserDefinedDestructor() {}
};
HasUserDefinedDestructor
has a user-provided destructor.
Per [class.dtor]/6:
A destructor is trivial if it is not user-provided and if: [...]
Otherwise, the destructor is non-trivial.
Therefore, HasUserDefinedDestructor
has a non-trivial destructor.
Per [meta.unary.prop]:
template <class T, class... Args>
struct is_trivially_constructible;
Condition: is_constructible_v<T, Args...>
is true
and the variable definition for is_constructible
, as defined below, is
known to call no operation that is not trivial ([basic.types],
[special]).
Pre-condition: T
and all types in the parameter pack Args
shall be a complete type, cv void
, or an array of unknown bound.
template <class T>
struct is_trivially_copy_constructible;
Condition: For a referenceable type T
, the same result as is_trivially_constructible_v<T, const T&>
, otherwise false
.
Pre-condition: T
shall be a complete type, cv void
, or an array of unknown bound.
template <class T>
struct is_trivially_move_constructible;
Condition: For a referenceable type T
, the same result as is_trivially_constructible_v<T, T&&>
, otherwise false
.
Pre-condition: T
shall be a complete type, cv void
, or an array of unknown bound.
Per [meta.unary.prop]/8:
The predicate condition for a template specialization
is_constructible<T, Args...>
shall be satisfied if and only if the
following variable definition would be well-formed for some invented
variable t
:
T t(declval<Args>()...);
[ Note: These tokens are never interpreted as a function
declaration. — end note ] Access checking is performed as if
in a context unrelated to T
and any of the Args
. Only the validity
of the immediate context of the variable initialization is considered.
[ Note: The evaluation of the initialization can result in side
effects such as the instantiation of class template specializations
and function template specializations, the generation of
implicitly-defined functions, and so on. Such side effects are not in
the “immediate context” and can result in the program being
ill-formed. — end note ]
The variable definition is supposed to "call" the destructor even though it seems that the destructor is not called at the place of the defintion. Therefore, std::is_trivially_move_constructible<HUDD>::value
is false
, as is std::is_trivially_copy_constructible<HUDD>::value
.
= default
for your destructor. – Rrhagia