c++language-lawyerc++20trivially-copyable

Why is a class trivially copyable with all private special member functions?


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.


Solution

  • 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?