我对在以下代码中使用std :: move()感到困惑:
如果我在(2)处取消注释行,则输出将为:1 2 3
,但是如果我在(1)处取消注释行,则输出将为空,这意味着调用了std::vector
的move构造函数!
为什么我们必须在(1)处再次调用std::move
才能调用std::vector
的move构造函数?
我的理解是std::move
获得其参数的r-value
,所以为什么我们必须在(1)获得r-value
的{{1}}?
我认为(2)的这一行r-value
更具逻辑性,应该使_v = rv;
移动构造函数以在没有std::vector
的情况下被调用,因为std::move
本身就是{{1} }首先。
rv
答案 0 :(得分:1)
每个命名对象都是左值ref about Lvalue:
变量,函数,模板参数对象的名称(自 C ++ 20)或数据成员(无论类型如何),例如std :: cin或 std :: endl。 即使变量的类型是右值引用, 由名称组成的表达式是左值表达式;
vector
有两个赋值运算符重载,一个重载左值引用,另一个重载右值引用。
vector::operator=(const vector&) // copy assignment operator
vector::operator=(vector&&) // move assignment operator
当Lvalue作为operator=
的参数传递时,调用引用Lvalue的重载。
Details here
当一个函数同时具有右值引用和左值引用时 重载,右值引用重载绑定到右值(包括 prvalue和xvalues),而左值引用重载绑定 到左值
通过std::move(rv);
,您将rv
-左值转换为右值引用,并调用了采用右值参考的operator=
。否则,左值将绑定到左值参考,并且矢量将被复制而不是被移动。