Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Returning std::vector by value

It is often said that in C++11 it is sane to return std::vector by value.

In C++03 this was mostly true as RVO should optimize away the copy. But that should scared most developers away.

  • In C++11 will a returned std::vector local variable always be moved?
  • What if that vector is a member of a local variable instead of a local variable itself?
  • Obviously returning a global variable will not be moved. What other cases will it not be moved?
like image 444
deft_code Avatar asked Jun 28 '12 15:06

deft_code


People also ask

How do you return a vector value in C++?

In order to code a vector in C++, the vector library has to be included in the program. The vector library has the vector class from which vector objects can be instantiated (created). using namespace std; A vector of strings is used.

Can vector be passed by value?

In the case of passing a vector as a parameter in any function of C++, the things are not different. We can pass a vector either by value or by reference.

WHAT IS BACK () in vectors C++?

vector::back()This function can be used to fetch the last element of a vector container.

Does vector Pop_back return value?

Return value The pop_back() function does not return anything.


2 Answers

First, every time a copy could be elided before, it can still be elided now, and moves can be elided in the same situations. For the rest of this post I'll assume that elision doesn't happen for some reason (pretend the compiler writer was lazy in a bad way).

In C++11 will a returned std::vector local variable always be moved?

Every time the criteria for copy elision are met, or the variable is explicitly std::moved.

What if that vector is a member of a local variable instead of a local variable itself?

It won't be moved unless explicitly std::moved.

Obviously returning a global variable will not be moved. What other cases will it not be moved?

Every time the criteria for copy elision are not met and the variable is not explicitly std::moved.

None of those is a valid reason to not to return by value. Return by value is ok, because even when the value is not automatically moved you can force it with std::move.

like image 57
R. Martinho Fernandes Avatar answered Sep 17 '22 04:09

R. Martinho Fernandes


In C++11 will a returned std::vector local variable always be moved?

For a local variable, even a by-value parameter, the compiler has to always attempt to move it first (if neither the move nor the copy can be elided for whatever reason, even if the criteria are met). If that fails, it tries again with a copy:

§12.8 [class.copy] p32

When the criteria for elision of a copy operation are met or would be met save for the fact that the source object is a function parameter, and the object to be copied is designated by an lvalue, overload resolution to select the constructor for the copy is first performed as if the object were designated by an rvalue. If overload resolution fails, or if the type of the first parameter of the selected constructor is not an rvalue reference to the object’s type (possibly cv-qualified), overload resolution is performed again, considering the object as an lvalue. [ Note: This two-stage overload resolution must be performed regardless of whether copy elision will occur. It determines the constructor to be called if elision is not performed, and the selected constructor must be accessible even if the call is elided. —end note ]

What if that vector is a member of a local variable instead of a local variable itself?

A subobject will not be tried to be moved, as that doesn't meet the criteria for copy elision. (Which is dumb, IMHO, but that's how it currently is. I don't think the two should be linked, since a subobject can perfectly fine be moved if it's local.)

Obviously returning a global variable will not be moved. What other cases will it not be moved?

A reference will obviously not be moved. Other than that, I can't really think of anything else.

like image 22
Xeo Avatar answered Sep 21 '22 04:09

Xeo