The r-value reference only binds to rvalues. In the above code,
Other(std::string &&) will not be considered. So only problem might be if the function
std::string & but moved it internally.
The only way to get r-value out of l-value is a
std::move. So as long as you take care not to use
std::move on function argument you received by l-value reference, there will be no surprises.
Moving something you received by l-value reference should be considered a bug. Unfortunately the rules of the language itself are unable to catch it, so it's a job for a static checker. I don't know whether any of them does already though.
Of course a function taking a non-const l-value reference could always screw up the passed object and the move just adds another way to do it, but the problem already existed.
I would generally recommend avoiding functions taking non-const l-value references, because functions modifying their argument are never particularly readable. A method is expected to modify it's invocant (unless it's a getter), but modifying other arguments makes the data flow more complicated and less obvious. In C++11 move makes returning objects almost as efficient as modifying reference and
std::tie allow returning multiple values, so most uses of argument modifying can be rewritten without significant loss of efficiency.
As for proper use of
std::move note that most efficient way to write setters that were previously written taking const reference and copied from it should now take by value and move from it. The argument construction in caller will do move if possible and copy otherwise.
Otherwould allow it to move out of
void Other(std::string &). Semantically, I think none. As Jan correctly says, that’s simply a bug.