<iterator> 中定義了迭代器得使用方法,主要得模版類有:
插入迭代器
插入迭代器是一種迭代器適配器,帶有一個(gè)容器參數(shù),并生成一個(gè)迭代器,用于在指定的容器中插入元素。通過插入迭代器賦值時(shí),迭代器將會(huì)插入一個(gè)新的元素。C++語言提供了三種插入器,其差別在于插入元素的位置不同:
back_inserter,創(chuàng)建使用push_back實(shí)現(xiàn)插入的迭代器,其使用一個(gè)對(duì)象作為實(shí)參將一個(gè)新元素插入到容器得后端
front_inserter的操作類似于back_inserter:該函數(shù)將創(chuàng)建一個(gè)迭代器,調(diào)用它所關(guān)聯(lián)的基礎(chǔ)容器的push_front成員函數(shù)代替賦值操作。
注意:只有當(dāng)容器提供push_front操作時(shí),才能使用front_inserter。在vector或其他沒有push_front運(yùn)算的容器上使用front_inserter,將產(chǎn)生錯(cuò)誤。
inserter使用insert實(shí)現(xiàn)插入操作,inserter還帶有第二個(gè)實(shí)參:指向插入起始位置的迭代器,inserter總是在它的迭代器參數(shù)所標(biāo)明的位置前面插入新元素。
流迭代器
雖然iostream類型不是容器,但標(biāo)準(zhǔn)庫同樣提供了在iostream對(duì)象上使用的迭代
器:istream_iterator用于讀取讀入流,而ostream_iterator用于寫輸出流。這些迭代器將它們所對(duì)應(yīng)的流視為特定類型的元素
序列。使用流迭代器時(shí),可以用泛型算法從流對(duì)象中讀數(shù)據(jù)(或?qū)?shù)據(jù)寫到流對(duì)象中)。
istream_iterator<T> in(strm); |
創(chuàng)建從輸入流strm中讀取T類型對(duì)象的istream_iterator對(duì)象,strm是一個(gè)輸入流 |
istream_iterator<T> in; |
istream_iterator對(duì)象的超出末端迭代器 |
ostream_iterator<T> out(strm); |
創(chuàng)建將T類型的對(duì)象寫到輸出流strm的ostream_iterator對(duì)象 |
ostream_iterator<T> out(strm, delim); |
創(chuàng)建將T類型的對(duì)象寫到輸出流strm的ostream_iterator對(duì)象,在寫入過程中使用delim作為元素的分隔符。delim是以空字符結(jié)束的字符數(shù)組 |
流迭代器只定義了最基本的迭代器操作:自增、引用和賦值。此外,可比較兩個(gè)istream迭代器是否相等(或不等)。而ostream迭代器則不提供比較運(yùn)算。
流迭代器的限制:
(1)不可能從ostream_iterator對(duì)象讀入,也不可能寫到istream_iterator對(duì)象中;
(2)一旦給ostream_iterator對(duì)象賦了一個(gè)值,寫入就提交了。賦值后,沒有辦法再改變這個(gè)值。此外,ostream_iterator對(duì)象中每個(gè)不同的值都只能正好輸出一次。
(3)ostream_iterator沒有->操作符。
測(cè)試:
#include <iostream>
#include <vector>
#include <iterator>
using namespace std;
int main() {
istream_iterator<int> in_iter(cin);
istream_iterator<int> eof;
//vector<int> vec(in_iter, eof); //do the same work as following loop
vector<int> vec;
while (in_iter != eof)
vec.push_back(*in_iter++); //*in_iter可以取出輸入流中得元素
vector<int>::const_iterator it = vec.begin();
for(; it != vec.end(); ++it)
cout<<*it<<endl;
return 0;
}
#include <iostream>
#include <iterator>
using namespace std;
int main() {
ostream_iterator<string> out_iter(cout, ""n");
istream_iterator<string> in_iter(cin), eof;
while (in_iter != eof)
*out_iter++ = *in_iter++;
return 0;
}
反向迭代器
反向迭代器是一種反向遍歷容器的迭代器。也就是,從最后一個(gè)元素到第一個(gè)元素遍歷容器。反向迭代器將自增(和自減)的含義反過來了:對(duì)于反向迭代器,++運(yùn)算將訪問前一個(gè)元素,而--運(yùn)算則訪問下一個(gè)元素。
(1)反向迭代器需要使用自減操作符:標(biāo)準(zhǔn)容器上的迭代器(reverse_iterator)既支持自增運(yùn)算,也支持自減運(yùn)算。但是,流迭代器由于不能反向遍歷流,因此流迭代器不能創(chuàng)建反向迭代器。
(2)可以通過reverse_iterator::base()將反向迭代器轉(zhuǎn)換為普通迭代器使用,從逆序得到普通次序。
測(cè)試:
#include <iostream>
#include <string>
#include <iterator>
#include <algorithm>
using namespace std;
int main() {
string str = "this 'sentence' is a test";
cout<<str<<endl;
string::iterator it1 = find(str.begin(), str.end(), '"'');
string::iterator it2 = find(++it1, str.end(), '"'');
cout<<string(it1, it2)<<endl;
string::reverse_iterator rit1 = find(str.rbegin(), str.rend(), '"'');
string::reverse_iterator rit2 = find(++rit1, str.rend(), '"'');
cout<<string(rit1, rit2)<<endl;
cout<<string(rit2.base(), rit1.base())<<endl;
getchar();
return 0;
}
不同的迭代器支持不同的操作集,而各種算法也要求相應(yīng)的迭代器具有最小的操作集。因此,可以將算法的迭代器分為下面五類:
輸入迭代器
(input iterator) |
讀,不能寫。支持的操作集:==, !=, 前綴++, 后綴++, *, ->。例如,find, accumulate算法要求這類迭代器。 |
輸出迭代器
(output iterator) |
寫,不能讀。支持的操作集:前綴++, 后綴++, *(只能出現(xiàn)在賦值運(yùn)算的左操作數(shù)上)。推出迭代器要求每個(gè)迭代器必須正好寫入一次。例如,ostream_iterator是輸出迭代器,copy算法使用這類迭代器。 |
前向迭代器(forward iterator) |
讀和寫,支持輸入迭代器和輸出迭代器提供的所有操作,還支持對(duì)同一個(gè)元素的多次讀寫。例如,replace算法需要這種迭代器。 |
雙向迭代器(bidirectional iterator) |
讀和寫,除了支持前向迭代器的所有操作,還支持前綴--和后綴--,即支持雙向遍歷容器。例如,reverse算法要求這類迭代器。標(biāo)準(zhǔn)庫容器中提供的迭代器都至少達(dá)到雙向迭代器的要求。 |
隨機(jī)訪問迭代器(random-access iterator) |
讀和寫。提供在常量時(shí)間內(nèi)訪問容器任意位置的功能。支持完整的迭代器操作集:1)關(guān)系運(yùn)算:==, !=, <, <=, >,
>=;2)算術(shù)運(yùn)算:it + n, it - n, it += n, it -= n以及it1 -
it2;3)下標(biāo)運(yùn)算:it[n],等價(jià)于*(it + n)。需要隨機(jī)訪問迭代器的泛型算法包括sort算法。例如,vector, deque,
string迭代器是隨機(jī)訪問迭代器,用作訪問內(nèi)置數(shù)組元素的指針也是隨機(jī)訪問迭代器。 |
除了輸出迭代器,其他類別的迭代器形成了一個(gè)層次結(jié)構(gòu):需要低級(jí)類別迭代器的地方,可使用任意一種更高級(jí)的迭代器。例如,對(duì)于需要輸入迭代器的算法,可傳
遞前向、雙向或隨機(jī)訪問迭代器調(diào)用該算法。而反之則不行。注意:向算法傳遞無效的迭代器類別所引起的錯(cuò)誤,無法保證會(huì)在編譯時(shí)被捕獲到。
map, set, list類型提供雙向迭代器,而string,
vector和deque容器上定義的迭代器都是隨機(jī)訪問迭代器,用作訪問內(nèi)置數(shù)組元素的指針也是隨機(jī)訪問迭代器。istream_iterator是輸
入迭代器,ostream_iterator是輸出迭代器。
另外,雖然map和set類型提供雙向迭代器,但關(guān)聯(lián)容器只能使用這部分算法的一個(gè)子集。因?yàn)殛P(guān)聯(lián)容器的鍵是const對(duì)象。因此,關(guān)聯(lián)容器不能使用任何
寫序列元素的算法。只能使用與關(guān)聯(lián)容器綁在一起的迭代器來提供用于讀操作的實(shí)參。因此,在處理算法時(shí),最好將關(guān)聯(lián)容器上的迭代器視為支持自減運(yùn)算的輸入迭
代器,而不是完整的雙向迭代器。
posted on 2010-08-27 15:55
何克勤 閱讀(1068)
評(píng)論(0) 編輯 收藏 所屬分類:
C/C++