Isl*_*een 12 c++ move c++11 c++14 stdmove
我对std::move()在下面的代码中使用感到困惑:
如果我在 (2) 处取消注释行,输出将是:1 2 3但如果我在 (1) 处取消注释行,输出将什么都不是,这意味着std::vector调用了移动构造函数!
为什么我们必须再次调用std::moveat (1) 来调用移动构造函数std::vector?
我的理解是std::move得到r-value其参数的话,为什么我们要得到r-value的r-value在(1)?
我认为_v = rv;(2) 中的这一行更合乎逻辑,应该使std::vector移动构造函数不被调用,std::move因为rv它首先是r-value引用。
template <class T>
class A
{
public:
void set(std::vector<T> & lv)
{
}
void set(std::vector<T> && rv)
{
//_v = std::move(rv); (1)
//_v = rv; (2)
}
private:
std::vector<T> _v;
};
int main()
{
std::vector<int> vec{1,2,3};
A<int> a;
a.set(std::move(vec));
for(auto &item : vec)
cout << item << " ";
cout << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
raf*_*x07 11
每个命名对象都是关于 Lvalue 的Lvalue引用:
变量、函数、模板参数对象(C++20 起)或数据成员的名称,无论类型如何,例如 std::cin 或 std::endl。即使变量的类型是右值引用, 由其名称组成的表达式也是左值表达式;
vector 有两个赋值运算符的重载,一个用于左值引用,另一个用于右值引用。
vector::operator=(const vector&) // copy assignment operator
vector::operator=(vector&&) // move assignment operator
Run Code Online (Sandbox Code Playgroud)
当 Lvalue 作为 的参数传递时,会调用采用 Lvalue 引用的重载operator=。
详情在这里
当函数同时具有右值引用和左值引用重载时,右值引用重载绑定到右值(包括纯右值和 xvalues),而左值引用重载绑定到左值
通过std::move(rv);您将rv- Lvalue 转换为 Rvalue 引用,并且operator=调用了 Rvalue 引用。否则,左值绑定到左值引用,向量被复制而不是被移动。