This is due to a late-breaking change in the move-semantics rules for C++11. The original move proposal did not automatically move when by-value function arguments appeared on the return clause. However by late in the C++11 process, that language feature was added.
Prior to the language feature being added, for_each
"was moved". At that time the move on the return statement was necessary. But it became unnecessary, though harmless by the time C++11 shipped.
LWG issue 2747 corrected this for C++17.
As to your first followup question, I am not a compiler writer, but my best guess is: It is not currently legal to elide the return from a function parameter (that much I know), and I'm guessing as to why it isn't legal is that no one has figured out how to implement it, and thus no one has had the motivation to change the standard to make it legal.
Second follow up: No, C++17 does not enforce elision in this case. The rules remain the same as for C++11 in this case, save for the fact that the redundant move from for_each
is no longer specified.
From the comments below:
Why do you say it's not legal to elide the return from a function parameter?
I'm referencing N4660, which is C++17, but there is similar wording in C++98/03/11/14 ... backup, it has recently been protected. See N4659 instead (just as good):
15.8.3 Copy/move elision [class.copy.elision]
When certain criteria are met, an implementation is allowed to omit the copy/move construction of a class object, ...
- in a
return
statement in a function with a class return type, when the expression is the name of a non-volatile automatic object (other than a function parameter or a variable introduced by the exception-declaration of a handler (18.3)) with the same type (ignoring cv-qualification) as the function return type, the copy/move operation can be omitted by constructing the automatic object directly into the function call’s return object
This language specifically disallows elision from function parameters.