为什么 vector 的 insert() 创建插入元素的副本并分配给副本,而不是插入的元素?

Why vector's insert() creates a copy of inserted element and assigns to the copy, not the inserted element?

考虑一个 insert(iterator position, const value_type &x) 调用:如果没有发生重新分配(容量!= 大小),那么在矢量的许多实现中我看到了这种行为:

     ...
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;
     ...

为什么不将 *__position 分配给 __x?创建副本不会导致额外浪费 space 吗?难道不能避免创建副本吗?

__x_copy 仅在未设置 __GXX_EXPERIMENTAL_CXX0X__ 宏时使用。这意味着它仅用于 C++98 和 C++03 模式。

如今,您可能不应该无缘无故地使用这些旧模式。

宏名称还表明您拥有 libstc++ 的旧副本。它于 2012 年被替换:https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=734f50238f863ae90d2e8caa2323aaa02380ff48


在移动容器的元素以释放应该插入新元素的位置之前,制作 __x 的副本,因为 __x 可能引用一个可能在此操作中重定位的容器元素,使引用无效。至少在我看来是这样。

如果我没记错的话,如果没有特定的先决条件另有说明,它曾经并且现在仍然允许将对同一容器的元素的引用传递给它的成员函数,只要这些是左值引用,而不是右值参考资料。