举例代码: 将一段数据复制到vector的首部 int data[5] = {0,1,2,3,4}; vectorint vInt; vInt.push_back(10); vInt.insert(vInt.begin(),data,data+5); vInt.clear(); vInt.push_back(10); copy(data, data+5, inserter(vInt,vInt.begin()));
举例代码:
将一段数据复制到vector的首部
vector<int> vInt;
vInt.push_back(10);
vInt.insert(vInt.begin(),data,data+5);
vInt.clear();
vInt.push_back(10);
copy(data, data+5, inserter(vInt,vInt.begin()));
查看copy方法的实现:
template<class InputIt, class OutputIt>OutputIt copy(InputIt first, InputIt last,
OutputIt d_first)
{
while (first != last) {
*d_first++ = *first++;
}
return
copy的第三个参数inserter是这样的:
template< class Containerstd::insert_iterator<Container> inserter( Container& c, typename Container::iterator i )
{
return std::insert_iterator<Container>(c, i);
}
insert_iterator的实现是这样的:
_LIBCPP_INLINE_VISIBILITY insert_iterator(_Container& __x, typename _Container::iterator __i): container(_VSTD::addressof(__x)), iter(__i) {}
对,其实就是构造了一个容器。
insert_iterator是一个类,不同的容器以模板泛型编程的方式被类实现。copy每调用一次inserter(d_first)即申请内存创建对象,随即进行数据复制(*d_first++ = *first++)。
insert方法中相关的底层函数调用
vector::__move_range ==> std::move_backward ==> std::move
move_range:
void
vector<_Tp, _Allocator>::__move_range(pointer __from_s, pointer __from_e, pointer __to)
{
pointer __old_last = this->__end_;
difference_type __n = __old_last - __to;
for (pointer __i = __from_s + __n; __i < __from_e; ++__i, ++this->__end_)
__alloc_traits::construct(this->__alloc(),
_VSTD::__to_raw_pointer(this->__end_),
_VSTD::move(*__i));
_VSTD::move_backward(__from_s, __from_s + __n, __old_last);
}
在循环中申请了一段区间内存,然后一次性move_backward.
move_backward
BidirIt2 move_backward(BidirIt1 first,
BidirIt1 last,
BidirIt2 d_last)
{
while (first != last) {
*(--d_last) = std::move(*(--last));
}
return
std::move的实现其实很简单:
template <class _Tp>inline _LIBCPP_INLINE_VISIBILITY
const _Tp&
move(const _Tp& __t)
{
return
故,从效果上来看,copy需要多次调用inserter函数,申请一段内存,每一次申请成功就复制数据;区间型insert这是在一个循环中申请够内存后再通过move_backward以逆向的方式一次性复制数据。此外,copy每次调用inserter都会发生移动,而insert因为是申请区间内存,故仅发生一次大的移动。
故从效率上看insert更好。