foreword
The original semantics of std::move() is to change an lvalue into an rvalue , which itself does not involve calling copy construction or calling move construction. Don't have the illusion that you use std::move() to call the move constructor. For example, in the following example, std::move() is used only to change a value from an lvalue to an rvalue, and has nothing to do with copying.
void foo(Test &&t) {
}
template <typename T>
void fun(T &&v) {
}
int main() {
Test t1;
// foo(t1); //编译错误,不能绑定左值
foo(std::move(t1)); //将左值变为右值,编译通过
Test t2;
fun(t2); //编译通过,但不涉及到拷贝
fun(std::move(t2)); //编译通过,也不涉及到拷贝
return 0;
}
So when it comes to copying, you must first pass by value, that is to say, copy A to B. At this time, if A is an lvalue, you can only call the copy constructor, and if A is an rvalue, you can call the move For the constructor, programmers can judge by themselves. If an lvalue is useless after copying it to another variable, then std::move(A) can be written in the copied place.
Generally, there are the following situations:
put in the container
std::vector<Test> vec;
vec.reserve(10);
Test t1;
vec.push_back(t1); //Copy Constructor....
Test t2;
vec.push_back(std::move(t2)); //Move Constructor...
Note that move will change the moved object. If the moved object is const, the copy constructor will still be called.
function argument list
void foo(Test t) {
}
int main() {
Test t1;
foo(t1); //Copy Constructor....
Test t2;
foo(std::move(t2)); //Move Constructor....
return 0;
}
function returns
Test foo() {
std::vector<Test> vec;
vec.resize(1);
return vec.front(); //Copy Constructor....
}
Test fun() {
std::vector<Test> vec;
vec.resize(1);
return std::move(vec.front()); //Move Constructor....
}
int main() {
foo();
fun();
return 0;
}
Advanced
Use universal reference + perfect forwarding to realize the semantics of lvalue-copy and rvalue-move
35 class Other {
36 public:
37 template <typename T>
38 Other(T &&t) : t_{std::forward<T>(t)} {
41 }
42 private:
43 Test t_;
44 };
45 int main() {
46 Test t;
47 Other o1(t); //拷贝
49 Other o2(std::move(t)); //移动
50 return 0;
51 }