Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

vector.push_back rvalue and copy-elision

I push_back a temporary object into a vector like this,

vector<A> vec;
vec.push_back(A("abc"));

will the compiler apply copy-elision to construct the temporary A("abc") directly into the vector, so that A's copy ctor won't be triggered when pushing the temporary object into vec.

like image 858
Alcott Avatar asked Aug 09 '12 02:08

Alcott


People also ask

Does vector Push_back make a copy?

Does vector Push_back make a copy? Yes, std::vector<T>::push_back() creates a copy of the argument and stores it in the vector.

What does Push_back do in a vector?

vector::push_back() push_back() function is used to push elements into a vector from the back. The new value is inserted into the vector at the end, after the current last element and the container size is increased by 1.

What does Push_back mean in C++?

push_back is one of the modifiers (used to modify a vector by removal or addition of elements) that exists in STL. C++ push_back() is a pre-defined function that is used to insert data or elements at the end of the vector or it pushes the element in the vector from the back.

Is vector Push_back slow?

In short, push_back is doing more than what operator[] is doing - which is why it is slower (and more accurate).


2 Answers

If you have a compiler that supports rvalue references, it will be moved into the vector, which is sometimes quite cheap.

An alternative to that is to directly construct the object in the vector, which can be done with vec.emplace_back("abc");. This only invokes one constructor.

Both of these are C++11 features. Copy elision is not allowed here, so without those features the copy will still be made.

However, if the copy constructor has no observable side-effects (which it shouldn't have anyway), a smart compiler may still perform that optimisation, because the "as-if" rule allows any optimisation that results in the same observable behaviour. I don't know if any current compiler does that, though. If not, I doubt anyone will spend the effort to add such an optimisation because rvalue references put an end to that need.

like image 53
R. Martinho Fernandes Avatar answered Nov 15 '22 15:11

R. Martinho Fernandes


In the general case, it cannot be done, it could potentially be done here as vector is a template and the code might be inlined, giving more information to the optimizer to do it's job and relieving some of the requirements of function calls.

In the general case, copy elision works by placing the two objects over the same location in memory and having just two names to refer to a single object. The problem in this case would be that one of the arguments must be located inside the vector (dynamically allocated, at a particular position), and the other is an argument to the function, which might be bound by the calling convention to a particular position in the stack. If that is the case, then the compiler will not be able to optimize the copy.

like image 24
David Rodríguez - dribeas Avatar answered Nov 15 '22 16:11

David Rodríguez - dribeas