为什么要使用 std::move 尽管参数是右值引用
Why to use std::move despite the parameter is an r-value reference
我对在下面的代码中使用 std::move()
感到困惑:
如果我在 (2) 处取消注释行,输出将是:1 2 3
但如果我在 (1) 处取消注释行,输出将是空的,这意味着调用了 std::vector
的移动构造函数!
为什么我们必须在 (1) 处再次调用 std::move
才能调用 std::vector
的移动构造函数?
我的理解是std::move
得到它参数的r-value
那么,为什么我们必须在(1)处得到r-value
的r-value
?
我认为 (2) 处的这一行 _v = rv;
更合乎逻辑,应该使 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;
}
Every named object is a Lvalue:
the name of a variable, a function, a template parameter object (since
C++20), or a data member, regardless of type, such as std::cin or
std::endl. Even if the variable's type is rvalue reference, the
expression consisting of its name is an lvalue expression;
vector
有两个赋值运算符重载,一个用于左值引用,另一个用于右值引用。
vector::operator=(const vector&) // copy assignment operator
vector::operator=(vector&&) // move assignment operator
当左值作为 operator=
的参数传递时,调用采用左值引用的重载。
Details here
when a function has both rvalue reference and lvalue reference
overloads, the rvalue reference overload binds to rvalues (including
both prvalues and xvalues), while the lvalue reference overload binds
to lvalues
通过 std::move(rv);
将 rv
- 左值转换为右值引用,并调用采用右值引用的 operator=
。否则,左值绑定到左值引用并且向量被复制而不是被移动。
我对在下面的代码中使用 std::move()
感到困惑:
如果我在 (2) 处取消注释行,输出将是:1 2 3
但如果我在 (1) 处取消注释行,输出将是空的,这意味着调用了 std::vector
的移动构造函数!
为什么我们必须在 (1) 处再次调用 std::move
才能调用 std::vector
的移动构造函数?
我的理解是std::move
得到它参数的r-value
那么,为什么我们必须在(1)处得到r-value
的r-value
?
我认为 (2) 处的这一行 _v = rv;
更合乎逻辑,应该使 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;
}
Every named object is a Lvalue:
the name of a variable, a function, a template parameter object (since C++20), or a data member, regardless of type, such as std::cin or std::endl. Even if the variable's type is rvalue reference, the expression consisting of its name is an lvalue expression;
vector
有两个赋值运算符重载,一个用于左值引用,另一个用于右值引用。
vector::operator=(const vector&) // copy assignment operator
vector::operator=(vector&&) // move assignment operator
当左值作为 operator=
的参数传递时,调用采用左值引用的重载。
Details here
when a function has both rvalue reference and lvalue reference overloads, the rvalue reference overload binds to rvalues (including both prvalues and xvalues), while the lvalue reference overload binds to lvalues
通过 std::move(rv);
将 rv
- 左值转换为右值引用,并调用采用右值引用的 operator=
。否则,左值绑定到左值引用并且向量被复制而不是被移动。