關於C++標準庫中的remove_copy,copy,remove,replace函數

本篇文章主要關於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.

所以是可以自加運算來指向下一個位置。





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章