例子:
代码:

int main(int argc, char *argv[])
{
    vector<Base1> B1s;
    for( int i = 0; i < 1000; ++i )
    {
        B1s.push_back( Base1() );
    }
    cout << "capacity: " << B1s.capacity() << ", size: " << B1s.size() << endl; 
    B1s.erase( B1s.begin() + 10, B1s.end() );
    cout << "capacity: " << B1s.capacity() << ", size: " << B1s.size() << endl;
    vector<Base1>(B1s).swap(B1s); 
    cout << "capacity: " << B1s.capacity() << ", size: " << B1s.size() << endl;
    return 0;
}

执行:

capacity: 1024, size: 1000
capacity: 1024, size: 10
capacity: 10, size: 10

解释:vector<Base1>(B1s)构建了一个临时对象,该对象具有B1s在erase之后的大小。
B1s在erase之后元素个数改变了,但是容积没有变。经过swap操作之后,临时对象和B1s完成了属性互换。
使用这一技巧还能得到容器的最小体积。

    vector<Base1>().swap(B1s);
    cout << "capacity: " << B1s.capacity() << ", size: " << B1s.size() << endl;
    // capacity: 0, size: 0

vector中的swap

template <class _Tp, class _Allocator>
void
vector<_Tp, _Allocator>::swap(vector& __x)
#if _LIBCPP_STD_VER >= 14
    _NOEXCEPT_DEBUG
#else
    _NOEXCEPT_DEBUG_(!__alloc_traits::propagate_on_container_swap::value ||
                __is_nothrow_swappable<allocator_type>::value)
#endif
{
    _LIBCPP_ASSERT(__alloc_traits::propagate_on_container_swap::value ||
                   this->__alloc() == __x.__alloc(),
                   "vector::swap: Either propagate_on_container_swap must be true"
                   " or the allocators must compare equal");
    _VSTD::swap(this->__begin_, __x.__begin_);
    _VSTD::swap(this->__end_, __x.__end_);
    _VSTD::swap(this->__end_cap(), __x.__end_cap());
    __swap_allocator(this->__alloc(), __x.__alloc(),
        integral_constant<bool,__alloc_traits::propagate_on_container_swap::value>());
#if _LIBCPP_DEBUG_LEVEL >= 2
    __get_db()->swap(this, &__x);
#endif  // _LIBCPP_DEBUG_LEVEL >= 2
}

可以发现,vector的begin,end迭代器发生了互换,连__end_cap_(包括pointer, allocator_type)也被交换了。故,这也影响了容器的内部数值与容器大小capacity。
所以,我们可以使用这种方法来快速将使用过的vector容器重新打回原形:vector<int>().swap(v1)

string中的swap

template <class _CharT, class _Traits, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
void
basic_string<_CharT, _Traits, _Allocator>::swap(basic_string& __str)
#if _LIBCPP_STD_VER >= 14
        _NOEXCEPT_DEBUG
#else
        _NOEXCEPT_DEBUG_(!__alloc_traits::propagate_on_container_swap::value ||
                    __is_nothrow_swappable<allocator_type>::value)
#endif
{
#if _LIBCPP_DEBUG_LEVEL >= 2
    if (!__is_long())
        __get_db()->__invalidate_all(this);
    if (!__str.__is_long())
        __get_db()->__invalidate_all(&__str);
    __get_db()->swap(this, &__str);
#endif
    _LIBCPP_ASSERT(
        __alloc_traits::propagate_on_container_swap::value ||
        __alloc_traits::is_always_equal::value ||
        __alloc() == __str.__alloc(), "swapping non-equal allocators");
    _VSTD::swap(__r_.first(), __str.__r_.first());
    __swap_allocator(__alloc(), __str.__alloc());
}

看代码,貌似比vector少一些东西,但是具体我说不上来。

分类: C plus plus

发表评论

电子邮件地址不会被公开。 必填项已用*标注