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.