如何使用移动的物体?

时间:2010-10-06 12:42:01

标签: c++ c++11 move-semantics

移动对象后,它必须是可破坏的:

T obj;
func(std::move(obj));
// don't use obj and let it be destroyed as normal

但是obj还能做些什么呢?你能把另一个物体移进去吗?

T obj;
func(std::move(obj));
obj = std::move(other);

这取决于确切的类型吗? (例如,std :: vector可以为所有T提供不能依赖的特定保证。)除了移动对象上的破坏之外,所有类型是否需要甚至理智?

5 个答案:

答案 0 :(得分:6)

是的,您可以将另一个对象移入其中。 std :: swap就是这样做的。

答案 1 :(得分:6)

C ++ 0x的当前草案要求可以销毁或分配移动的对象。如果将对象传递给标准库中的函数,则可以假设这一切。

通常认为良好做法是确保移动的对象是满足所有不变量的类型的“工作”对象。但是,它处于未指定的状态 - 如果它是一个容器,你不知道它有多少元素,或它们是什么,但你应该能够调用size()和{{1} },并查询它。

目前的草案尚不清楚标准库类型本身的要求,并且C ++委员会对此进行了积极的讨论。

答案 2 :(得分:1)

那是类型语义。你决定。由您决定如何实施此举。

通常,状态应与使用非参数构造函数获得的状态相同。

顺便说一下。如果要在指针(或其他一些可移动类)后面存储数据块,那么move才有意义。

答案 3 :(得分:1)

这取决于类代码。如果类没有rvalue引用构造函数和赋值运算符,则忽略std :: move。 std :: move不会移动任何东西,它只允许将其参数视为右值引用,如果有适当的函数可用。

正确书写&& constructor和operator =必须使参数实例处于某种一致状态,如空字符串,并且对象应该可用。如果有operator =,则可以将另一个对象正确分配给这样的空实例。

编辑。

通常,std :: move应该用于将移动语义应用于非rvalue的变量,但实际上它是:

SomeClass::SomeClass(SomeClass&& v)
{
    // Inside of this function, v is not rvalue anymore. But I know that actually 
    // this is rvalue, and use std::move
    OtherFunction(std::move(v));
}

在这种情况下,对v的最低要求是它应该能够毫无问题地死亡。

当std :: move用于实际上不是rvalue引用的变量时,实际上,这个变量的可用性可能是未定义的。对于我自己的课程,我会确保这种情况的某种一致性。对于另一个类 - 它取决于特定的类实现,但我不会将std :: move应用于实际上不是rvalue引用的对象。我真的不知道标准中是如何定义的(以及它是否已定义)。

答案 4 :(得分:0)

正如我最终从评论中所理解的那样。你应该检查一下:http://www.boost.org/doc/libs/1_44_0/libs/concept_check/concept_check.htm

这将允许您检查作为概念的模板参数提供的类型(类型的特征)。我不确定他们是否已经有一个可移动的。