7
#include <vector>

using namespace std;

struct A
{
    A(const vector<int>&) {}
    A(vector<int>&&) {}
};

A f()
{
    vector<int> coll;
    return A{ coll }; // Which constructor of A will be called as per C++11?
}

int main()
{
    f();
}

Is coll an xvalue in return A{ coll };?

Does C++11 guarantee A(vector<int>&&) will be called when f returns?

xmllmx
  • 39,765
  • 26
  • 162
  • 323
  • In your example, `A{coll}` will be constructed in the caller context and will use the constructor `A(const vector&)`. – Oliv Feb 27 '17 at 12:40

1 Answers1

11

C++11 does not allow coll to be moved from. It only permits implicit moves in return statements when you do return <identifier>, where <identifier> is the name of a local variable. Any expression more complicated than that will not implicitly move.

And expressions more complex than that will not undergo any form of elision.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
  • 4
    +1; Note that there where quirks, where if the type of `` didn't match the return'd type, it wasn't moved. This was fixed in either a defect report or a change in C++14, I forget which; but, if you are using a legacy compiler (or risk using one), a `move` when the types do not match exactly may be wise (and has no cost). Meanwhile, when the types match exactly, the `move` would block elision. This is only of concern if you are using relatively ancient compilers. – Yakk - Adam Nevraumont Feb 24 '17 at 16:31
  • @vsoftco: Oh, the *expression* is a prvalue, and it will behave as such. But `coll` will not be moved into `A`, and that's what the question was asking. – Nicol Bolas Feb 24 '17 at 16:36
  • @NicolBolas Thanks! Yes, realized after I wrote the comment. At first I thought that `A` has a move ctor and that the question was about the `A` object itself. – vsoftco Feb 24 '17 at 16:37