本篇文章主要关于remove_copy和copy函数中的OutputIterator参数的选定。
以remove_copy为例:
template<class InputIterator, class OutputIterator, class Type> OutputIterator remove_copy( InputIterator _First, InputIterator _Last, OutputIterator _Result, const Type& _Val );
OutputIterator参数的选定,在这里只讨论begin()和back_inserter():
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <iterator>
using namespace std;
int main(void)
{
string str1,str2;
str1 = "abc_def_ghi_jkl_mno_pqr";
cout<<str1<<endl;
//用back_inserter函数,不需要指定str2的大小
remove_copy(str1.begin(), str1.end(), back_inserter(str2), '_');
cout<<str2<<endl;
//复制str1到v1中
vector<char> v1,v2;
for (vector<char>::size_type i = 0;i < str1.length();i++)
v1.push_back(str1[i]);
for (vector<char>::size_type i = 0;i < v1.size();i++)
cout<<v1[i];
cout<<" <- v1"<<endl;
//用back_inserter函数,不需要指定v2的大小
remove_copy(v1.begin(), v1.end(), back_inserter(v2), '_');
for (vector<char>::size_type i = 0;i < v2.size();i++)
cout<<v2[i];
cout<<" <- v2"<<endl;
//用begin函数,必须指定v3的大小(否则出错),而且这个大小必须比要复制进去的元素总数大
vector<char> v3(20);
remove_copy(v1.begin(), v1.end(), v3.begin(), '_');
for (vector<char>::size_type i = 0;i < v3.size();i++)
cout<<v3[i];
cout<<" <- v3"<<endl;
return 0;
}
输出结果为:
从结果看出,用begin函数时对于容器的大小必须先给定,很难把握。所以用函数back_inserter就有了优势。
关于这个原因我们可以看看标准库中remove_copy的源代码:
template<class _InIt,
class _OutIt,
class _Ty> inline
_OutIt _Remove_copy(_InIt _First, _InIt _Last,
_OutIt _Dest, const _Ty& _Val, _Range_checked_iterator_tag)
{ // copy omitting each matching _Val
_DEBUG_RANGE(_First, _Last);
_DEBUG_POINTER(_Dest);
for (; _First != _Last; ++_First)
if (!(*_First == _Val))
*_Dest++ = *_First;
return (_Dest);
}
如果容器没有预先指定一个足够的大小,实参为begin函数时,*Dest++将会超出范围。back_inserter函数返回back_insert_iterator这个迭代器有一个重载符号
operator++ | Increments the back_insert_iterator to the next location into which a value may be stored. |