C++ move构造函数和std::move混淆
我正在阅读有关移动构造函数和移动赋值运算符的内容。 老实说,我现在得到的只是困惑。现在我有一节课:C++ move构造函数和std::move混淆,c++,c++11,move,rvalue-reference,C++,C++11,Move,Rvalue Reference,我正在阅读有关移动构造函数和移动赋值运算符的内容。 老实说,我现在得到的只是困惑。现在我有一节课: class A{ public: int key; int value; A(){key = 3; value = 4;} //Simple move constructor A(A&& B){ A.key = std::move(B.key); A.value = std::move(B.value);}
class A{
public:
int key;
int value;
A(){key = 3; value = 4;}
//Simple move constructor
A(A&& B){ A.key = std::move(B.key);
A.value = std::move(B.value);}
};
B
是一个右值引用,为什么您可以将std::move
应用于一个右值引用的成员B.key
和B.value
之后,这两个项都已失效,但是B
作为类A
的对象如何失效A(A())
,A()
显然是一个rvlaue,那么A()
可以被std::move
移动吗?为什么int添加(int&&z){
int x=标准:移动(z);
int y=标准:移动(z);
返回x+y;
}
add(5)
,如何移动5
,为什么?
请注意,z
已经移动了两次,在第一次移动z
之后,它已经无效,您如何再次移动它
foo(T&&Z)
(T
,Z
可以是任何东西)时,在定义的主体中,既然Z
已经被右值引用传递,我到底为什么要使用std::move(Z)
李>
您必须理解,
std::move
不会移动任何东西,而是将其参数“标记”为右值引用。从技术上讲,它将类型转换为右值引用。然后,由相应的移动构造函数或移动赋值运算符移动的右值引用。对于仅包含具有普通移动因子/赋值运算符的成员的对象,移动因子/赋值运算符是普通的,只是复制。通常,对象的move-ctor/assignment操作符调用其所有成员的move-ctor/assignment操作符
所以,每当你写信的时候
int x = 10;
int y = std::move(x);
这是不同的。moved\u s
的move构造函数启动,并“窃取”(即交换内部指针等)s
的资源,因为后者是右值引用。最后,s
将不包含任何元素
B
是对象的名称。一旦一个引用被绑定,它就会命名一个对象。“右值引用”、“左值引用”和“命名对象”之间的区别仅适用于在达到这一步之前如何绑定名称B.key
是作为此函数调用的参数提供的对象中变量的名称
A.key=std::move(B.key)
调用int
的内置赋值定义(这是一个简单赋值,不是函数调用),它只是一个副本。因此B.key
保留其值
A(B())
,B
必须是尚未定义的类型名。(你的意思是A(A())
?如果是,那么答案是“是”)Z.foo
时,请使用std::move(Z.foo)
,而不是从Z.foo
复制隐式生成的move构造函数/赋值运算符将移动(而不是复制)-如果我们讨论的是一个包含字符串成员变量的类,那么这个区别很重要,例如,您可以详细介绍第5项吗?例如,如果我有
ab代码>我可以做A(b)
为什么?@user2345484关于第5项,不,您不能,您需要使用move
每当您向函数传递除右值以外的任何值时。如果尝试传递左值,它将无法编译。在这个注释上面的示例中,您可以这样做,因为A
很可能有一个默认的复制ctor,它将进行复制。要强制移动,请通过std::move(b)
将b
转换为右值引用,然后a
的移动向量将生效。@user2345484名称std::move
在我看来是非常不幸的,它应该被命名为lvalue
或decay\u lvalue
或其他名称,而不是move
,因为它给人一种错误的印象,即函数“执行”了一些非平凡的操作。如果查看std::move
的定义,您将看到它使用了包装函数std::remove\u reference
。看看后者,了解它是如何工作的。例如,在第4项的函数中,我不明白为什么要执行std::move(z)
,对于A(A())
?因为z
已经作为右值引用传递,并且std::move(z)
还返回右值引用。
string s = "some string";
string moved_s = std::move(s); // here we tell the compiler that we can "steal" the resource of s