Code is like:
#include <iostream>
#include <type_traits>
class A
{
A() = default;
A(const A&) = default;
A(A&&) = default;
A& operator=(const A&) = default;
A& operator=(A&&) = default;
~A() = default;
int a;
};
int main()
{
std::cout << std::boolalpha <<
std::is_trivially_copy_assignable_v<A> << " " <<
std::is_trivially_copy_constructible_v<A> << " " <<
std::is_trivially_move_assignable_v<A> << " " <<
std::is_trivially_move_constructible_v<A> << " " <<
std::is_trivially_destructible_v<A> << " " <<
std::is_trivially_copyable_v<A> << "\n";
return 0;
}
And the output is false false false false false true. But according to cppreference:
A trivially copyable class is a class that
- has at least one eligible copy constructor, move constructor, copy assignment operator, or move assignment operator,
- each eligible copy constructor is trivial
- each eligible move constructor is trivial
- each eligible copy assignment operator is trivial
- each eligible move assignment operator is trivial, and
- has a non-deleted trivial destructor.
So from the first four boolean outputs, none of the copy constructor, move constructor, copy assignment operator and move assignment operator is trivial, so it's supposed to be non-trivially-copyable; However, the last output boolean is true.
Note: You can make ~A() = default and A() = default public so that you can create objects, but the core question is still the same.
The question is not can an instance of this class actually be copied?
std::is_trivially_copyable answers
if you copied this instance with a bytewise copy, would the result be the same as copying using a copy operator?
std::is_trivially_copy_constructible_v<T> doesn't check whether T has a trivial copy constructor, which is what trivially-copyable is based on.
Instead it checks whether a definition of a variable of the form
T t(u);
where u is a variable of type const T, would be well-formed in a context unrelated to T and that the construction of the variable would use only trivial functions. This includes a check for accessibility and a check for a non-deleted accesible destructor.
The same applies in similar form to the other _constructible_ and _assignable_ traits. These traits are not directly related to is_trivially_copyable. The is_trivially_copyable trait tells you whether you can use memcpy to copy objects of the type. It doesn't tell you whether copy/move-construction/assignment will be possible and trivial, which is what the other traits are for.
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