I wonder for such obvious thing (just to detect if it's rvalue) wouldn't it be better to just optimize it away in compiler instead of adding to the already complicated language itself?
#include <vector>
#include <string>
struct A
{
// is it a good idea to move str_vec into my_strings?
// yes, if and only if the vector that str_vec refers to is an rvalue
// no, if it happens to be an lvalue
// we had no mechanism to distinguish between the two cases
explicit A( std::vector<std::string>& str_vec ) : my_strings(str_vec) {}
// is it a good idea to move my_strings into the anonymous return value?
// yes, if what *this refers to is an rvalue
// no, if it happens to be an lvalue
// we had no mechanism to distinguish between the two cases
std::vector<std::string> strings() const { return my_strings ; }
std::vector<std::string> my_strings ;
};
I wonder for such obvious thing (just to detect if it's rvalue) ...
Rvalues are detected automatically. It is only when we want to move from something that is not an rvalue that we have to use std::move.
... wouldn't it be better to just optimize it away in compiler instead of adding to the already complicated language itself?
It is true that move semantics has made the language more complicated but it doesn't necessarily mean it has to be much more complicated to use. Move semantics is first and foremost an optimization. If you don't need the extra performance (which sometimes is negligible anyway) you can most of the time just ignore that move semantics exist, like the times before C++11. The standard library uses move semantics and the compiler will automatically provide move constructor and move assignment operators for classes in many situations so you will probably still benefit from it even though you are not using it explicitly.