gpt4 book ai didi

c++ - 琐碎的复制和 move 操作是否不同?

转载 作者:搜寻专家 更新时间:2023-10-31 02:14:42 28 4
gpt4 key购买 nike

让我们看看一些简单的可 move 构造和(不是简单的)可复制构造(但仍然可复制构造)的用户定义(类)类型 A:

struct A
{
A() = default;
A(A const &) {}
A(A &&) = default;
};

然后 A 的 move ( move 构造或 move 赋值)从字面上执行以下操作:将源按位复制到目标,尽管操作名称为“move ” .在平凡的 move 中,右手边(正式地)不是 const,但是整个操作的平凡性要求右手边(实际)不可改变,不是吗?在我看来,这意味着平凡的复制操作和平凡的 move 操作在它们的深层本质上完全相同(在内存、内存布局、位等方面)。我说得对吗?

如果是这样,那么我想,如果我在用户代码中看到平凡的 move 构造类型,而不是平凡的复制构造类型,那么我显然看到了一些反模式。我说得对吗?

是否有这样一个人造但可用的类型的例子,它不是平凡的复制构造/可分配的,而是平凡的 move 构造/可分配的?

最佳答案

是否存在一个类型可以有一个普通的复制构造函数而没有一个普通的 move 构造函数的用例?当然。

例如,拥有一个在 move 时始终为空的指针包装类型可能很有用。复制构造函数没有理由不重要,但 move 构造函数必须将旧值设置为 NULL。

template<typename T>
class empty_on_move
{
T *ptr_;

public:
empty_on_move(const empty_on_move&) = default;
empty_on_move(empty_on_move &&other) : ptr_(other.ptr_) {other.ptr_ = nullptr;}
...
};

empty_on_move不拥有该对象,这就是为什么可以拥有它的多个拷贝的原因。它的存在只是为了确保当您离开它时,指针处于易于理解的状态。因此,is_trivially_copy_constructible<empty_on_move<T>>是真的,而is_trivially_move_constructible<empty_on_move<T>>是假的。

它主要用于其他想要提供特定行为指针的类内部。这样,您就不必显式地将代码写入它们的 move 构造函数/赋值中,以将这些字段清零。


话虽这么说,你真的问错了问题。为什么?因为答案并不重要。

复制/move 构造函数/赋值的琐碎性唯一重要的是当您需要类型为 Trivially Copyable 时. 那个属性允许使用memcpy诸如此类的事情,不是个别操作的琐碎。平凡可复制属性要求复制/move 构造函数/赋值和析构函数所有都是平凡的(在 C++14 中,要求它们可以是平凡的或删除的,但至少有一个必须是非平凡的-删除)。

如果您正在围绕某种类型编写包装器(或编写求和/乘积类型),并且您想要公开该类型的属性,您只需要关心公开平凡可复制性。也就是说,如果 T (或 Ts... )是平凡可复制的,那么你的类型也应该是平凡可复制的。

但除此之外,你不应该仅仅因为 T 就觉得需要一个简单的复制构造函数。

关于c++ - 琐碎的复制和 move 操作是否不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39611510/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com