std::vector::swap是如何实现的?
How is std::vector::swap implemented?
我想到将数组从一个 std::vector
复制到另一个的最快方法是交换它们的指针,只要您不再关心要交换的向量。所以我去寻找并找到了 std::vector::swap
。我假设交换指针是如何实现的,但我没有在参考资料中看到解释。
来自http://en.cppreference.com/w/cpp/container/vector/swap:
Exchanges the contents of the container with those of other. Does not invoke any move, copy, or swap operations on individual elements.
我觉得这很清楚。
更新,回应 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);
}
一个简化的、最小的矢量实现可能有类似以下成员的东西来管理矢量中的数据:
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)
};
A swap()
操作只会交换每个 simplified_vector 的 'guts',将所有动态分配的缓冲区(以及其中包含的元素)留在原地。只有指向那些动态分配的指针会四处移动:
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
实现可能使用与这个简单示例不完全相同的技术(例如移动构建临时对象),但我认为它传达了一般概念。
我想到将数组从一个 std::vector
复制到另一个的最快方法是交换它们的指针,只要您不再关心要交换的向量。所以我去寻找并找到了 std::vector::swap
。我假设交换指针是如何实现的,但我没有在参考资料中看到解释。
来自http://en.cppreference.com/w/cpp/container/vector/swap:
Exchanges the contents of the container with those of other. Does not invoke any move, copy, or swap operations on individual elements.
我觉得这很清楚。
更新,回应 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);
}
一个简化的、最小的矢量实现可能有类似以下成员的东西来管理矢量中的数据:
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)
};
A swap()
操作只会交换每个 simplified_vector 的 'guts',将所有动态分配的缓冲区(以及其中包含的元素)留在原地。只有指向那些动态分配的指针会四处移动:
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
实现可能使用与这个简单示例不完全相同的技术(例如移动构建临时对象),但我认为它传达了一般概念。