The following excerpt compiles in Clang-libstdc++ or Clang-libc++, GCC, many of their versions and all three versions of the language since 11 (14 & 17):
#include <type_traits>
struct HasUserDefinedDestructor {
~HasUserDefinedDestructor() {}
};
using HUDD = HasUserDefinedDestructor;
static_assert(not std::is_trivially_move_constructible<HUDD>::value, "");
static_assert(not std::is_trivially_copy_constructible<HUDD>::value, "");
This surprises me, since a copy only requires trivial operations.
Is this an error in the compilers/libraries or does the standard say somewhere that having a user defined destructor makes the copy and move constructors not trivial?
Edit: Why this is not a repeat of default construction question: Given the comments we know "noexceptness" and triviality of constructors are affected by the noexceptness and triviality of the destructor, but before knowing that all of these traits are related the questions are different. Having this question allows anybody to see this is related
is_trivially_constructible
is defined as follows (bold is mine):
is_constructible_v<T,Args...>
istrue
and the variable definition foris_constructible
, as defined below, is known to call no operation that is not trivial
«Defined below» is [meta.unary.op]/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 variablet
:
T t(declval<Args>()...);
So yes, is_trivially_[copy|move]_constructible_v
is false
when the destructor is not trivial.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With