为什么 class with destructor 不是平凡移动可构造的?

Why class with destructor is not trivially move constructible?

这是为什么class:

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

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

不是简单地移动可构建的吗?

Why class with destructor is not trivially move constructible?

因为标准是这样说的:

[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]).

is_trivially_move_constructible_v<T> 定义为 is_trivially_constructible_v<T, T&&> [meta.unary.prop]

is_trivially_constructible_v<T, T&&> 被定义为 is_constructible_v<T, T&&> 并且“is_constructible_v 的变量定义已知不会调用不重要的操作。

is_construcible_v<T, T&&> 被定义为 true 当且仅当变量定义是格式正确的 [meta.unary.prop/8]:

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

只考虑变量初始化的直接上下文的有效性。

根据这些知识,is_constructible_v<T, T&&> 是真的吗?是的。析构函数 inhibits the defaulted move constructor. But it does not inhibit 默认的复制构造函数。这已被弃用,但可能永远不会改变。变量定义是一个复制结构,并且格式正确。

定义是否调用了一个不平凡的操作?复制构造函数是微不足道的。该定义不调用析构函数。所以,众所周知,所有的操作都是微不足道的。

因此,我认为is_trivially_move_constructible_v<T>是正确的。(而且你的编译器有错误)

另请参阅:https://cplusplus.github.io/LWG/lwg-active.html#2827