Why vector's insert() creates a copy of inserted element and assigns to the copy, not the inserted element?
Consider an insert(iterator position, const value_type &x)
call: if no reallocation is happening (capacity != size), then in many implementations of the vector I saw this behavior:
...
template<typename _Tp, typename _Alloc>
void
vector<_Tp, _Alloc>::
_M_insert_aux(iterator __position, const _Tp& __x)
#endif
{
...
if (this->_M_impl._M_finish != this->_M_impl._M_end_of_storage)
{
this->_M_impl.construct(this->_M_impl._M_finish,
_GLIBCXX_MOVE(*(this->_M_impl._M_finish
- 1)));
++this->_M_impl._M_finish;
#ifndef __GXX_EXPERIMENTAL_CXX0X__
_Tp __x_copy = __x;
#endif
_GLIBCXX_MOVE_BACKWARD3(__position.base(),
this->_M_impl._M_finish - 2,
this->_M_impl._M_finish - 1);
#ifndef __GXX_EXPERIMENTAL_CXX0X__
*__position = __x_copy;
...
Why not assign *__position
to __x
? Doesn't creating a copy result in additional waste of space? Couldn't one get away with avoiding creating the copy?
The __x_copy
is only used if the __GXX_EXPERIMENTAL_CXX0X__
macro isn't set. This means it is only used in C++98 and C++03 mode.
Nowadays you probably shouldn't be using these old modes without a reason.
The macro name also indicates that you have an old copy of libstc++. It was replaced in 2012: https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=734f50238f863ae90d2e8caa2323aaa02380ff48
Before moving elements of the container to free up the location at which the new element is supposed to be inserted, a copy of __x
is made because it is possible that __x
refers to an element of the container which may be relocated in this operation, invalidating the reference. At least that is what it looks like to me.
If I remember correctly, it was, and still is, allowed to pass references to elements of the same container to its member functions if there are no specific preconditions stating otherwise, as long as these are lvalue references, not rvalue references.