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?
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?
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
Because the standard says so: