[C/C++]_[初級]_[關於OutputIterator的簡單介紹]
阿新 • • 發佈:2018-12-01
場景
1.我們在使用演算法庫時, 免不了需要對集合進行排序, 複製, 移動等, 而對集合的元素進行操作就需要用到列舉(itereator).
2.我們一般是對已存在的集合進行遍歷, 刪除, 但是如果需要複製一個集合A內的元素到一個集合B內時如何操作, 這時候列舉怎麼使用? 用列舉能很方便進行多元素新增, 而不需要使用效率低下的 for 迴圈.
說明
1.Iterator可以理解為一種可以對集合的元素進行標識和來回移動的型別, 也可以理解為一個抽象的指標. 它包括5 種類型的列舉: InputIterator, OutputIterator, ForwardIterator, BidirectionalIterator, 和 RandomAccessIterator
ContiguousIterator
.
2.OutputIterator 是一種列舉, 它可以寫入指向的元素. ForwardIterator, BidirectionalIterator, 或者 RandomAccessIterator
都是 OutputIterator的一種. OutputIterator 滿足我們最常用的幾種操作:
3.std::back_inserter 能快速的建立一個通過容器push_back函式新增元素的列舉, 當然容器要有push_back函式.
4.std::inserter 能快速的建立一個通過容器的insert函式新增元素的列舉, 當然容器要有insert函式, 沒有編譯報錯.
*r = o // 這個比較特殊, r首先解引用後賦值, 之後r遞增1, 指向下一個元素位置.
++r
r++
*r++ = o
例子
#include <assert.h>
#include <iostream>
#include <utility>
#include <iterator>
#include <set>
#include <typeinfO>
template <class A>
static void PrintArray(A& a)
{
std::cout << typeid (a).name() << std::endl;
if(a.begin() == a.end())
return;
auto ite = a.begin();
std::cout << "(";
std::cout << *ite;
ite++;
for(; ite != a.end();++ite){
std::cout << "," << *ite;
}
std::cout << ")" << std::endl;
}
void TestIterator()
{
std::vector<int> v;
// back_insert_iterator 的用法, operator= 插入一個數據, 因為是back列舉, 每次都會呼叫
// container的push_back函式.
auto& itev = std::back_inserter(v);
itev = 1;
itev = 2;
itev = 3;
itev = 4;
itev = 5;
itev = 5;
PrintArray(v);
std::vector<int> f;
f.push_back(-1);
f.push_back(-2);
f.push_back(-3);
PrintArray(f);
// 複製 v內的陣列到f, 從f的第2個位置開始.
std::copy(v.begin(),v.end(),std::inserter(f,std::next(f.begin())));
PrintArray(f);
// 複製vector到set, 過濾掉重複的.
// std::inserter 每次都會呼叫容器的insert函式.
std::set<int> s;
std::copy(v.begin(), v.end(),std::inserter(s,s.begin()));
PrintArray(s);
std::vector<int> result;
std::sort(v.begin(),v.end());
std::sort(f.begin(),f.end());
// 獲取兩個集合的差集
// 如果直接使用 result.begin()的話會崩潰,
// vector iterator not incrementable;
// 因為 result.begin()不是OutputIterator, iterator不可以遞增,result本身沒有元素.
//std::set_difference(f.begin(),f.end(),v.begin(),v.end(),result.begin());
std::set_difference(f.begin(),f.end(),v.begin(),v.end(),std::back_inserter(result));
PrintArray(result);
}
輸出:
class std::vector<int,class std::allocator<int> >
(1,2,3,4,5,5)
class std::vector<int,class std::allocator<int> >
(-1,-2,-3)
class std::vector<int,class std::allocator<int> >
(-1,1,2,3,4,5,5,-2,-3)
class std::set<int,struct std::less<int>,class std::allocator<int> >
(1,2,3,4,5)
class std::vector<int,class std::allocator<int> >
(-3,-2,-1)
參考
OutputIterator
concept-Iterator
iterator
back_inserter
insert_iterator
inserter
next
copy