In this case, since the return value has the name ( f ), it will apply to the NRVO (named return value).
So, the technical answer, based only on formulations, is that the lack of RVO will not prevent copying, since NRVO can still resolve it.
The past, I believe that the choice between move / copy of the return value can / will depend on the definition of Foo - there are certain times when it will be copied instead of moving, for example, if you explicitly deleted the move constructor and move assignment operators, or you did not define the construct displacement / assignment, and it cannot be synthesized implicitly.
Edit: [answer to edited question]: having a move constructor still does not guarantee that the result will be moved. One obvious example would be if you removed the move assignment operator and assigned the result (rather than using it to initialize). In this case, the operator of assigning remote operations will prevent the return value from being moved.
To answer what you may have received, however, the general rule is that the move will be done if possible, and it will be returned to copying if and only if something does not allow the result to be moved.
Jerry Coffin
source share