If I use std::move on a stack object in the current scope, the contents are moved to destination leaving the source empty.
#include <iostream> #include <string> #include <utility> #include <vector> int main() { std::string str("stackoverflow"); std::vector<std::string> vec; vec.emplace_back(std::move(str)); std::cout << "vec[0]: " << vec[0] << std::endl; std::cout << "str: " << str << std::endl; } Result:
vec[0]: stackoverflow str: If I use the std::move for a rvalue or const lvalue function arguments, the contents are copied.
#include <iostream> #include <memory> #include <vector> #include <utility> void process_copy(std::vector<int> const & vec_) { std::vector<int> vec(vec_); vec.push_back(22); std::cout << "In process_copy (const &): " << std::endl; for(int & i : vec) std::cout << i << ' '; std::cout << std::endl; } void process_copy(std::vector<int> && vec_) { std::vector<int> vec(vec_); vec.push_back(99); std::cout << "In process_copy (&&): " << std::endl; for(int & i : vec) std::cout << i << ' '; std::cout << std::endl; } int main() { std::vector<int> v = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; process_copy(std::move(v)); std::cout << "In main: " << std::endl; for(int & i : v) std::cout << i << ' '; std::cout << std::endl; std::cout << "size: " << v.size() << std::endl; } Result:
In process_copy (&&): 0 1 2 3 4 5 6 7 8 9 99 In main: 0 1 2 3 4 5 6 7 8 9 size: 10 Why is the behavior of std::move different?
std::movedoesn't actually move anything. It is just a cast to rvalue reference. Whether that rvalue reference is subsequently moved or copied depends on context and whether or not the object implements move operations and whether or not the source object isconst.actually moving the ownership of the datais the move constructor of the std::string. In the second example, you're just sending an rvalue ref. You can manually take the ownership of the passed std::vector here.