为什么vector template function assign有两个版本来区分
why vector template function assign has two version to distinguish
我正在阅读 SGI STL 的源代码。当我阅读assign实现的源代码时,我发现有两个版本,一个用于输入迭代器,一个用于前向迭代器。我知道输入迭代器支持读和++,正向迭代器支持读和写和++,为什么它有输入和正向迭代器两个版本?
template <class _Tp, class _Alloc> template <class _InputIter>
void vector<_Tp, _Alloc>::_M_assign_aux(_InputIter __first, _InputIter __last,
input_iterator_tag) {
iterator __cur = begin();
for ( ; __first != __last && __cur != end(); ++__cur, ++__first)
*__cur = *__first;
if (__first == __last)
erase(__cur, end());
else
insert(end(), __first, __last);
}
template <class _Tp, class _Alloc> template <class _ForwardIter>
void
vector<_Tp, _Alloc>::_M_assign_aux(_ForwardIter __first, _ForwardIter __last,
forward_iterator_tag) {
size_type __len = 0;
distance(__first, __last, __len);
if (__len > capacity()) {
iterator __tmp = _M_allocate_and_copy(__len, __first, __last);
destroy(_M_start, _M_finish);
_M_deallocate(_M_start, _M_end_of_storage - _M_start);
_M_start = __tmp;
_M_end_of_storage = _M_finish = _M_start + __len;
}
else if (size() >= __len) {
iterator __new_finish = copy(__first, __last, _M_start);
destroy(__new_finish, _M_finish);
_M_finish = __new_finish;
}
else {
_ForwardIter __mid = __first;
advance(__mid, size());
copy(__first, __mid, _M_start);
_M_finish = uninitialized_copy(__mid, __last, _M_finish);
}
}
I know that input iterator support read and ++, forward iterator
support read and write and ++
不完全是。这里的关键点是前向迭代器是 multipass。您只能迭代(非前向)输入迭代器一次,而您可以多次迭代前向迭代器。
这意味着使用前向迭代器,可以使用distance()
提前获取新范围内的元素数量,如果需要分配必要的内存量,然后遍历范围再次复制元素。这保证您最多重新分配一次。
对于输入迭代器,您不能这样做,因为 distance()
调用会迭代整个范围,您不能再次迭代它以实际读取元素。
我正在阅读 SGI STL 的源代码。当我阅读assign实现的源代码时,我发现有两个版本,一个用于输入迭代器,一个用于前向迭代器。我知道输入迭代器支持读和++,正向迭代器支持读和写和++,为什么它有输入和正向迭代器两个版本?
template <class _Tp, class _Alloc> template <class _InputIter>
void vector<_Tp, _Alloc>::_M_assign_aux(_InputIter __first, _InputIter __last,
input_iterator_tag) {
iterator __cur = begin();
for ( ; __first != __last && __cur != end(); ++__cur, ++__first)
*__cur = *__first;
if (__first == __last)
erase(__cur, end());
else
insert(end(), __first, __last);
}
template <class _Tp, class _Alloc> template <class _ForwardIter>
void
vector<_Tp, _Alloc>::_M_assign_aux(_ForwardIter __first, _ForwardIter __last,
forward_iterator_tag) {
size_type __len = 0;
distance(__first, __last, __len);
if (__len > capacity()) {
iterator __tmp = _M_allocate_and_copy(__len, __first, __last);
destroy(_M_start, _M_finish);
_M_deallocate(_M_start, _M_end_of_storage - _M_start);
_M_start = __tmp;
_M_end_of_storage = _M_finish = _M_start + __len;
}
else if (size() >= __len) {
iterator __new_finish = copy(__first, __last, _M_start);
destroy(__new_finish, _M_finish);
_M_finish = __new_finish;
}
else {
_ForwardIter __mid = __first;
advance(__mid, size());
copy(__first, __mid, _M_start);
_M_finish = uninitialized_copy(__mid, __last, _M_finish);
}
}
I know that input iterator support read and ++, forward iterator support read and write and ++
不完全是。这里的关键点是前向迭代器是 multipass。您只能迭代(非前向)输入迭代器一次,而您可以多次迭代前向迭代器。
这意味着使用前向迭代器,可以使用distance()
提前获取新范围内的元素数量,如果需要分配必要的内存量,然后遍历范围再次复制元素。这保证您最多重新分配一次。
对于输入迭代器,您不能这样做,因为 distance()
调用会迭代整个范围,您不能再次迭代它以实际读取元素。