8

I have a function

struct foo {
    std::vector<int> v;
};

foo func();

will the vector inside foo be moved or copied when returning from the function?

Andy Prowl
  • 114,596
  • 21
  • 355
  • 432
yngccc
  • 5,344
  • 2
  • 18
  • 31
  • 4
    No, it will be moved. – Benjamin Lindley Feb 25 '13 at 19:04
  • 2
    It totally depends on what happens inside `func`. – Joseph Mansfield Feb 25 '13 at 19:04
  • @BoPersson Not quite, as that question is about returning a `vector`, while this is about returning a struct with the default move constructor and a `vector` member. –  Feb 25 '13 at 19:05
  • @delnan - No difference. The other question is about returning values in general, and covers this case. – Bo Persson Feb 25 '13 at 19:07
  • 2
    @BoPersson One thing that matters here, which I did not find anywhere in that question, is whether moving a struct without user-defined move constructor moves the members or copies them. I don't doubt this too has been asked and answered before, but the specific question you link to doesn't quite cut it IMHO. –  Feb 25 '13 at 19:10
  • @delnan - Ok, I don't think the people answering the other question even considered that returning a vector by itself or returning a vector inside a struct could be any different. It isn't. – Bo Persson Feb 25 '13 at 19:15
  • @BoPersson: Of course it is different: in one case, you return an object which explicitely defines a move constructor; in the other case, you return an object without any user-defined constructors. The two cases are obviously different, since the latter involves implicitely-defined constructors. – Luc Touraille Feb 27 '13 at 15:21
  • @Luc - Ok, I just don't see the difference. Answers to the other question say that when returning a vector from a function, it can be moved. And now we have an answer here saying that the vector inside a struct can also be moved - fine. – Bo Persson Feb 27 '13 at 15:30

1 Answers1

9

It will be moved.(*)

Since you do not provide an explicit move constructor for your foo class, the compiler will implicitly generate one for you that invokes the move constructor (if available) for all the members of your class. Since std::vector defines a move constructor, it will be invoked.

Per Paragraph 12.8/15 of the C++11 Standard:

The implicitly-defined copy/move constructor for a non-union class X performs a memberwise copy/move of its bases and members. [...]

Also notice, that the compiler is allowed to elide the call to the copy/move constructor of your class when returning an object by value. This optimization is called (Named) Return Value Optimization.

(*) I am assuming here that your use case is to create a local object with automatic storage inside foo() and return it.

Andy Prowl
  • 114,596
  • 21
  • 355
  • 432
  • It won't be moved if the `foo` it returns is perhaps a `foo` with static storage duration. There's probably some other cases too. But yes, I agree with you for the case that the asker is probably asking about. – Joseph Mansfield Feb 25 '13 at 19:07
  • 1
    @sftrabbit: OK, that's correct. I assumed that he wanted to returned a local object with automatic storage. Edited, thank you. – Andy Prowl Feb 25 '13 at 19:11
  • @BoPersson: I did mention that, although not RVO explicitly. I will do it. – Andy Prowl Feb 25 '13 at 19:11