If you compile this program with a C++11 compiler, the vector is not moved out of the function.
#include <vector>
using namespace std;
vector<int> create(bool cond) {
vector<int> a(1);
vector<int> b(2);
return cond ? a : b;
}
int main() {
vector<int> v = create(true);
return 0;
}
If you return the instance like this, it is moved.
if(cond) return a;
else return b;
Here is a demo on ideone.
I tried it with gcc 4.7.0 and MSVC10. Both behave the same way.
My guess why this happens is this:
The ternary operators type is an lvalue because it is evaluated before return statement is executed. At this point a and b are not yet xvalues (soon to expire).
Is this explanation correct?
Is this a defect in the standard?
This is clearly not the intended behaviour and a very common case in my opinion.
Here are the relevant Standard quotes:
12.8 paragraph 32:
paragraph 33:
Since the expression in
return (cond ? a : b);is not a simple variable name, it’s not eligible for copy elision or rvalue treatment. Maybe a bit unfortunate, but it’s easy to imagine stretching the example a little bit further at a time until you create a headache of an expectation for compiler implementations.You can of course get around all this by explicitly saying to
std::movethe return value when you know it’s safe.