It compiles, but I get the output 0 .
Here I am wondering why the code above does not move the substr correctly while the code below does (prints out 1):
In both cases abc is a temporary object inside of the function and gets deleted after the function is left. But why does the second version work and the first one does not?
cat.substr(1, 1)
And as my last question. Why doesn't return std::move(abc.substr(1, 1));
work?
- std::move just gives you an r-value reference to the provided object. No new object is created.
- Rvalue references are still references... so whatever object you're referring to must have a lifetime that exceeds that of the reference.
Your examples don't work because 'abc' has a scope that ends when no_sense ends. Therefore your return value is a reference to an object that no longer exists. It'd be the same as if you did an l-value reference.
You can only return a reference (r-value or l-value) if the object you're referring to has lifetime longer than the function. In both your examples, abc has a lifetime limited by the function -- so they're both bad. If it's working in one of them... it's a fluke -- you're accessing garbage memory.
In your first code it will automatically move orig because it's a local variable inside the function, that can't be used after the function is returned, so moving it is perfectly safe.
I guess line 4 in your second code is supposed to declare abc as a std::string. Returning a reference (ordinary reference or rvalue reference) to a local variable results in undefined behaviour because the variable will no longer exist after the function has returned so you end up with a reference to a non-existing object.
Here it is said, that the local variable new_values will be moved after the function ends. (If I understood correctly.)
Does that mean, that my code does not work, because I explicitly use std::move(abc); on a local variable?
But if I change the code to