【发布时间】:2015-08-22 03:10:39
【问题描述】:
libc++的std::vectorimplementation有以下insert的重载:
template <class _Tp, class _Allocator>
typename vector<_Tp, _Allocator>::iterator
vector<_Tp, _Allocator>::insert(const_iterator __position, const_reference __x)
{
pointer __p = this->__begin_ + (__position - begin());
if (this->__end_ < this->__end_cap())
{
__RAII_IncreaseAnnotator __annotator(*this);
if (__p == this->__end_)
{
__alloc_traits::construct(this->__alloc(),
_VSTD::__to_raw_pointer(this->__end_), __x);
++this->__end_;
}
else
{
__move_range(__p, this->__end_, __p + 1);
const_pointer __xr = pointer_traits<const_pointer>::pointer_to(__x);
if (__p <= __xr && __xr < this->__end_) // [*]
++__xr;
*__p = *__xr;
}
__annotator.__done();
}
else
{
allocator_type& __a = this->__alloc();
__split_buffer<value_type, allocator_type&> __v(__recommend(size() + 1), __p - this->__begin_, __a);
__v.push_back(__x);
__p = __swap_out_circular_buffer(__v, __p);
}
return __make_iter(__p);
}
... 和类似的,采用右值引用:
template <class _Tp, class _Allocator>
typename vector<_Tp, _Allocator>::iterator
vector<_Tp, _Allocator>::insert(const_iterator __position, value_type&& __x)
{
pointer __p = this->__begin_ + (__position - begin());
if (this->__end_ < this->__end_cap())
{
__RAII_IncreaseAnnotator __annotator(*this);
if (__p == this->__end_)
{
__alloc_traits::construct(this->__alloc(),
_VSTD::__to_raw_pointer(this->__end_),
_VSTD::move(__x));
++this->__end_;
}
else
{
__move_range(__p, this->__end_, __p + 1);
*__p = _VSTD::move(__x);
}
__annotator.__done();
}
else
{
allocator_type& __a = this->__alloc();
__split_buffer<value_type, allocator_type&> __v(__recommend(size() + 1), __p - this->__begin_, __a);
__v.push_back(_VSTD::move(__x));
__p = __swap_out_circular_buffer(__v, __p);
}
return __make_iter(__p);
}
第一次重载中标记[*]的分支的目的是什么?是标准要求的吗?为什么在第二次重载中没有它?我在 libstdc++ 中找不到等效的构造。
编辑:libstdc++solves通过创建临时副本来解决同样的问题。
【问题讨论】:
-
谢谢,现在看起来不错:-)