如果某个对象实际移动到另一个位置,原始对象支持的操作是什么?
为了详细说明,我有一个带有可用移动构造函数的T
类型。以下陈述
T x{constructor-args};
T y{std::move(x)};
使用对象x
可以完成所有操作(假设对象实际上使用x
的可用移动构造函数从y
移动到T
?
具体地,
x
肯定会被销毁。我可以假设移动后x
可以轻易破坏吗?x
分配或移动分配给新对象(我想是的,因为我看到很多swap
使用了这个)? 我可以构建一个新的对象对象来代替x
吗?如果允许这是允许的话,那么是否可以使用uninitialized_move
与(部分)重叠源和&目的地范围,如std::copy
,与std::uninitialized_copy
不同?
T z{some-args};
x = z; //or x = std::move(z);
T u{some-args};
new(&x) T{std::move(u)}; // or new(&x) T{u}; etc
答案 0 :(得分:3)
无论你定义它是什么。至少,由此产生 对象应该是可破坏的 - 它的析构函数将是 调用,对象的状态应该是这样的 没有问题。
标准库保证其对象是一些
连贯的国家。你可以调用任何成员函数:它是
未指明您得到的回报,但结果将是
连贯:如果你在已被移动的向量上调用size
,
您也可以使用小于该值的索引来调用operator[]
由size
返回(但在唯一合理的实施中,
size
将返回0,)。这可能不仅仅是什么
然而,有效使用所需;所有这些都是非常必要的
是调用析构函数将工作。
为了更清楚,以std::vector
为例:如果我们
假设通常的实现,有三个指针,开始,
结束和限制(或者他们被称为:限制意味着
一个超过分配内存的末尾,以便capacity()
返回limit - begin
)。搬家后,标准会
要求所有三个指针都为空。多数情况
实现中,不会访问限制指针
析构函数,因此可删除的宽松要求会
如果只将开始和结束指针设置为null,则会遇到。
答案 1 :(得分:2)
关于图书馆类型,标准说(17.6.5.15)
除非另有说明,否则此类移动对象应置于有效但未指定的状态。
这意味着它们至少应该是可破坏和可分配的。正如詹姆斯在下面提到的那样,该对象仍然应该遵循自己的界面。你自己的类型应遵循相同的想法。
你不应该使用placement-new来做这类事情。假设移动构造函数不存在,并使用operator =以与以前相同的方式编写代码。示例中的最后一行应为x=std::move(u);
或x=u;
。