Why can't these variables move around?

There are many missed opportunities in C ++ move semantics. I would like to understand the rationale for these reasons and why the standard is not more aggressive in determining when a variable should be moved in the following cases:

string f() { string s; return s + " "; } 

This calls operator+(const string&, const char*) , not operator+(string&&, const char*) , I believe because s is an lvalue. Could the standard say that with the last use of a local variable in a function, the variable should be considered movable?

I think a somewhat similar example:

 struct A { A(string&&); }; string g() { string s; return s; // s is moved } A h() { string s; return s; // s can't be moved! } 

g uses move semantics to move data from s to the return value, but h does not compile because s does not move to h . I believe this is because the standard has a special case for g , which says that if you return a local variable of the same type as the return type, the variable moves. Why is it not a rule that if you return a local variable, it moves regardless of its type?

+4
source share
2 answers

Simply put, this is an unnecessary limitation in the current standard, which makes automatic moves dependent on the availability of copy-elision.

Another example might be:

 struct X{ std::string s; }; std::string foo(){ X x; return xs; // no automatic move }; 

I opened a thread on the http://isocpp.org forum for future standard offers that you can see. On the advice of Richard Smith, I immediately sent a message to Mike Miller about the discovery of the main problem and received an answer:

[...] based on the above Richard, it sounds like a reasonable question, so I will open a problem for him in the next edition of the list of problems. Thanks.

So, for C ++ 14, all these restrictions are likely to disappear, and every time a local variable returns, you will get an automatic move.

Richard btw resume is:

More specifically, [class.copy] p31 has the rule that a copy can be deleted for the "return id-expression" statement; where the id expression names the local variable, and the variable has the same cv-unqualified type as the type of the returned function. It is assumed that we must perform an automatic transition at any time when we have a "return id-expression" statement; where the id expression names a local variable or function parameter, regardless of the type of variable.

+2
source

I am sure this may require moving the example, but then someone will come up with another case where they consider it โ€œobviousโ€ that s used for the last time, and therefore it should be moved.

Ultimately, you will have a standard that determines what kind of analysis of the data stream the compiler should perform. The authors decided to draw the line conservatively to allow implementations to be stupid in this regard. Programmers can always write std::move to change the copy to move.

Another possibility for the standard to say is that it is not indicated whether objects are moved or copied, provided that the code no longer uses them. This will allow you to realize as smart as she likes. Iโ€™m sure this would be a bad idea: in practice, users often donโ€™t care if their objects move, but sometimes they need to be developed.

+5
source

All Articles