8

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

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 做出你不能依赖的特定保证。)除了对移动对象的破坏之外,所有类型是否都支持某些东西是必需的,甚至是理智的?

4

5 回答 5

6

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

于 2010-10-06T12:52:11.353 回答
6

当前的 C++0x 草案要求可以销毁或分配已移出的对象。如果您将对象传递给标准库中的函数,那么这就是假设的全部。

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

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

于 2010-10-06T12:57:59.027 回答
1

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

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

编辑。

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

SomeClass::SomeClass(SomeClass&& v)
{
    // 在这个函数内部,v 不再是右值。但我知道实际上
    // 这是右值,并使用 std::move
    其他功能(标准::移动(v));
}

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

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

于 2010-10-06T12:55:23.010 回答
1

这就是类型语义。你决定。如何实施这一举措取决于您。

一般来说,状态应该与使用非参数构造函数获得的状态相同。

顺便提一句。move 仅在您将数据块存储在指针(或其他一些可移动类)后面时才有意义。

于 2010-10-06T12:52:18.933 回答
0

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

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

于 2010-10-06T13:36:01.967 回答