std::vector::swap 是如何实现的



我突然想到,将数组从一个std::vector复制到另一个的最快方法是交换它们的指针,只要你不再关心你要交换的向量。所以我去寻找,找到了std::vector::swap.我假设交换指针是它的实现方式,但我在参考中没有看到解释。

简化的最小向量实现可能具有类似于以下成员的内容来管理向量中的数据:

template <typename T>
class simple_vector
{
public:
    // ...
    static
    void swap(simple_vector<T>& x, simple_vector<T>& y);
private:
    T* elements;    // a pointer to the block of memory holding the elements in the vector
    size_t count;   // number of 'active' elements
    size_t allocated;   // number of elements allocated (not all of which are necessarily used at the moment)
};

swap()操作只会交换每个simplified_vector的"胆量",将所有动态分配的缓冲区(以及其中包含的元素)保留在原位。只有指向这些动态分配的指针才会移动:

template <typename T>
void simple_vector<T>::swap(simple_vector<T>& x, simple_vector<T>& y)
{
    T* tmp_elements = x.elements;
    size_t tmp_count = x.count;
    size_t tmp_allocated = x.allocated;
    x.elements = y.elements;
    x.count = y.count;
    x.allocated = y.allocated;
    y.elements = tmp_elements;
    y.count = tmp_count;
    y.allocated = tmp_allocated;
}

请注意,实际的std::vector实现可能使用与这个简单示例不完全相同的技术(例如移动构造临时),但我认为它传达了一般概念。

从 http://en.cppreference.com/w/cpp/container/vector/swap:

将容器的内容与其他容器的内容交换。不对单个元素调用任何移动、复制或交换操作。

这对我来说似乎很清楚。

更新,以回应OP的评论

我在 g++ 4.8.4 中看到以下内容:

      void
      swap(vector& __x)
#if __cplusplus >= 201103L
            noexcept(_Alloc_traits::_S_nothrow_swap())
#endif
      {
        this->_M_impl._M_swap_data(__x._M_impl);
        Alloc_traits::_S_on_swap(_M_get_Tp_allocator(),
                              __x._M_get_Tp_allocator());
      }

并且,这是_Vector_impl::M_swap_data的实现:

void _M_swap_data(_Vector_impl& __x)
{
  std::swap(_M_start, __x._M_start);
  std::swap(_M_finish, __x._M_finish);
  std::swap(_M_end_of_storage, __x._M_end_of_storage);
}

最新更新