3

It's well-known that you shouldn't use std::move when returning a local variable:

std::vector<int> return_vector(void)
{
    std::vector<int> tmp {1,2,3,4,5};
    return std::move(tmp); // DON'T DO THIS
}

But what about the case where your return expression contains tmp as a sub-expression?

std::tuple<vector<int>, size_t> return_tuple() const
{
    std::vector<int> tmp {1,2,3,4,5};
    return std::make_tuple(std::move(tmp), tmp.size());
}
ShadowRanger
  • 108,619
  • 9
  • 124
  • 184
MSalters
  • 159,923
  • 8
  • 140
  • 320
  • Yes, I know there's a bonus question hiding in there. – MSalters Oct 26 '20 at 16:32
  • 3
    Don't do this! The order in which `std::move(tmp)` and `tmp.size()` are evaluated is unspecified, so you may invoke a function on a moved-from object which may produce wrong results – dave Oct 26 '20 at 16:41
  • @dave: In this case, yeah, the example could use improvement; probably best to write the example as: `std::vector tmp {1,2,3,4,5};`, `auto size = tmp.size();`, `return std::make_tuple(std::move(tmp), auto);` just to remove that bit of bother from consideration. – ShadowRanger Oct 26 '20 at 16:43
  • 2
    Does this answer your question? [Return std::tuple and move semantics / copy elision](https://stackoverflow.com/questions/51521031/return-stdtuple-and-move-semantics-copy-elision) – Rane Oct 26 '20 at 18:42
  • 1
    @Rane: First time I've used the close privilege to close my own question :D – MSalters Oct 26 '20 at 21:15
  • @dave: You win the bonus. – MSalters Oct 26 '20 at 21:19
  • @dave: It’s not the `std::move` itself that’s the problem—`std::move` doesn’t move anything—but it’s true that the parameter might be initialized from the rvalue before the other argument is evaluated. – Davis Herring Oct 26 '20 at 22:51

0 Answers0