Why class with destructor is not trivially move constructible?

314 Views Asked by At

Why is this class:

class test_type {
public:
    ~test_type() {
        std::cout << "~()\n";
    }
};

// fails
static_assert(std::is_trivially_move_constructible_v<test_type>, "");

not trivially move constructible?

2

There are 2 best solutions below

3
On BEST ANSWER

Why class with destructor is not trivially move constructible?

Because the standard says so:

[class.prop]

A trivially copyable class is a class:

  • that has at least one eligible copy constructor, move constructor, copy assignment operator, or move assignment operator ([special], [class.copy.ctor], [class.copy.assign]),
  • where each eligible copy constructor, move constructor, copy assignment operator, and move assignment operator is trivial, and
  • that has a trivial, non-deleted destructor ([class.dtor]).
0
On

is_trivially_move_constructible_v<T> is defined to be is_trivially_constructible_v<T, T&&> [meta.unary.prop]

is_trivially_constructible_v<T, T&&> is by defined to be is_constructible_v<T, T&&> and the "variable definition for is_constructible_v is known to call no operation that is not trivial.

is_construcible_v<T, T&&> is defined to be true if and only if the variable definition is well-formed [meta.unary.prop/8]:

T t(declval<T&&>());

Only the validity of the immediate context of the variable initialization is considered.

With that knowledge, is is_constructible_v<T, T&&> true? Yes. A destructor inhibits the defaulted move constructor. But it does not inhibit the defaulted copy constructor. That is deprecated, but probably will never change. The variable definition is a copy construction, and is well-formed.

Does the definition call an operation that is not trivial? The copy constructor is trivial. The definition doesn't call a destructor. So, it is known that all operations are trivial.

Therefore, I think is_trivially_move_constructible_v<T> is true. (and your compiler has a bug)

See also: https://cplusplus.github.io/LWG/lwg-active.html#2827