为什么 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>
是正确的。(而且你的编译器有错误)
这是为什么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>
是正确的。(而且你的编译器有错误)