一、迭代器 iterator
容器的 iterator 類型每種容器類型都定義了自己的C++迭代器類型,如 vector:vector::iterator iter;這符語(yǔ)句定義了一個(gè)名為 iter 的變量,它的數(shù)據(jù)類型是 vector定義的 iterator 類型。每個(gè)標(biāo)準(zhǔn)庫(kù)容器類型都定義了一個(gè)名為 iterator 的成員,這里的 iterator 與迭代器實(shí)際類型的含義相同。begin 和 end 操作每種容器都定義了一對(duì)命名為 begin 和 end 的函數(shù),用于返回迭代器。如果容器中有元素的話,由 begin 返回的迭代器指向第一個(gè)元素: vector::iterator iter = ivec.begin();
上述語(yǔ)句把 iter 初始化為由名為 vector 操作返回的值。假設(shè) vector 不空,初始化后,iter 即指該元素為ivec[0]。
由 end 操作返回的C++迭代器指向 vector 的“末端元素的下一個(gè)”?!俺瞿┒说鳌保╫ff-the-end iterator)。表明它指向了一個(gè)不存在的元素。如果 vector 為空,begin 返回的迭代器與 end 返回的迭代器相同。
由 end 操作返回的迭代器并不指向 vector 中任何實(shí)際的元素,相反,它只是起一個(gè)哨兵(sentinel)的作用,表示我們已處理完 vector 中所有元素。
vector 迭代器的自增和解引用運(yùn)算
C++迭代器類型定義了一些操作來(lái)獲取迭代器所指向的元素,并允許程序員將迭代器從一個(gè)元素移動(dòng)到另一個(gè)元素。迭代器類型可使用解引用操作符(dereference operator)(*)來(lái)訪問(wèn)迭代器所指向的元素:
*iter = 0;
解引用操作符返回迭代器當(dāng)前所指向的元素。假設(shè) iter 指向 vector 對(duì)象 ivec 的第一元素,那么 *iter 和ivec[0] 就是指向同一個(gè)元素。上面這個(gè)語(yǔ)句的效果就是把這個(gè)元素的值賦為 0。迭代器使用自增操作符(1.4.1 節(jié))向前移動(dòng)迭代器指向容器中下一個(gè)元素。從邏輯上說(shuō),C++迭代器的自增操作和int 型對(duì)象的自增操作類似。對(duì) int 對(duì)象來(lái)說(shuō),操作結(jié)果就是把 int 型值“加 1”,而對(duì)迭代器對(duì)象則是把容器中的迭代器“向前移動(dòng)一個(gè)位置”。因此,如果 iter 指向第一個(gè)元素,則 ++iter 指向第二個(gè)元素。
由于 end 操作返回的迭代器不指向任何元素,因此不能對(duì)它進(jìn)行解引用或自增操作。
二、? 適配器adapter
有三種:容器適配器,迭代器適配器,函數(shù)適配器下面一一介紹
1.容器適配器:具體的有stack,queue,priority_queue,默認(rèn)的情況下,stack和queue基于deque而實(shí)現(xiàn)的,priority_queue在vector上實(shí)現(xiàn)的,可以根據(jù)第二個(gè)實(shí)參指定容器的類型,但一定要符合標(biāo)準(zhǔn),queue要求要有push_front操作因此不能建立在vector上面,priority_front要求有隨機(jī)訪問(wèn)的功能,因此建立在vector上面。優(yōu)先級(jí)隊(duì)列默認(rèn)采用<排序的
2.迭代適配器:插入器是一種迭代器適配器,帶有一個(gè)容器參數(shù),并生成一個(gè)迭代器,提供了三種插入器
3.函數(shù)適配器,用于擴(kuò)展一元和二元函數(shù)對(duì)象
綁定器:是一種函數(shù)適配器,它通過(guò)將一個(gè)一個(gè)操作數(shù)綁定到給定值而將二元函數(shù)對(duì)象轉(zhuǎn)換為一元函數(shù)對(duì)象,bind1st,和bind2nd分別將二元函數(shù)對(duì)象綁定到第一個(gè)參數(shù)和第二個(gè)參數(shù),由此將二元操作轉(zhuǎn)換成一元操作
求反器:標(biāo)準(zhǔn)庫(kù)定義了兩個(gè)求反器not1,not2分別針對(duì)于一元函數(shù)和二元函數(shù)
三、綁定bind
是這樣一種機(jī)制,它可以預(yù)先把指定可調(diào)用實(shí)體的某些參數(shù)綁定到已有的變量,產(chǎn)生一個(gè)新的可調(diào) 用實(shí)體,這種機(jī)制在回調(diào)函數(shù)的使用過(guò)程中也頗為有用。C++98中,有兩個(gè)函數(shù)bind1st和bind2nd,它們分別可以用來(lái)綁定functor的第 一個(gè)和第二個(gè)參數(shù),它們都是只可以綁定一個(gè)參數(shù)。各種限制,使得bind1st和bind2nd的可用性大大降低。
四、inserter
C++的迭代器適配器中常用的有插入迭代器(Insert Iterator)、流迭代器(Stream Iterator)和逆向迭代器(Reverse Iterator)等!
下面介紹三種插入迭代器:
1.Back Inserter
原理:其內(nèi)部調(diào)用push_back()
功能:在容器的尾端插入元素
限制:只有提供了push_back()成員函數(shù)的容器中,back inserter才能派上用場(chǎng)
適用:vector deque list
2.Front Inserter
原理:其內(nèi)部調(diào)用push_front()
功能:在容器的前端插入元素
限制:只有提供了push_front()成員函數(shù)的容器中,front inserter才能派上用場(chǎng)
適用:deque list
3.Inserter
原理:其內(nèi)部調(diào)用insert()
功能:在容器的指定位置插入元素
限制:只有提供了inset()成員函數(shù)的容器中,inserter才能派上用場(chǎng). 所有STL容器都提供了inset()函數(shù).
適用:所有STL容器
五 reverse-iterator
1. 定義反向迭代器(Reverse Iterator)是一種反向遍歷容器的迭代器。也就是,從最后一個(gè)元素到第一個(gè)元素遍歷容器。反向迭代器將自增(和自減)的含義反過(guò)來(lái)了:對(duì)于反向迭代器,++運(yùn)算將訪問(wèn)前一個(gè)元素,而--運(yùn)算則訪問(wèn)下一個(gè)元素。2. 作用(1)反向迭代器需要使用自減操作符:標(biāo)準(zhǔn)容器上的迭代器(reverse_iterator)既支持自增運(yùn)算,也支持自減運(yùn)算。但是,流迭代器由于不能反向遍歷流,因此流迭代器不能創(chuàng)建反向迭代器。(2)可以通過(guò)reverse_iterator::base()將反向迭代器轉(zhuǎn)換為普通迭代器使用,從逆序得到普通次序。這是因?yàn)椋河行┤萜鞯某蓡T函數(shù)只接受iterator類型的參數(shù),所以如果你想要在ri所指的位置插入一個(gè)新元素,你不能直接這么做,因?yàn)関ector的insert函數(shù)不接受reverse_iterator。如果你想要?jiǎng)h除ri 所指位置上的元素也會(huì)有同樣的問(wèn)題。erase成員函數(shù)會(huì)拒絕reverse_iterator,堅(jiān)持要求iterator。為了完成刪除和一些形式的插入操作,你必須先通過(guò)base函數(shù)將reverse_iterator轉(zhuǎn)換成iterator,然后用iterator來(lái)完成工作。3. 例子[cpp] view plain copy print?void test_reverse()? {? ? ? int a[] = {-2, -1, 0, 1, 2, 3, 4};? ? ? std::listlst(a, a + sizeof(a)/sizeof(int));? ? ? std::copy(lst.begin(), lst.end(), std::ostream_iterator(std::cout, " "));? ? ? std::cout << std::endl;? ? ? ? std::list::reverse_iterator rit = lst.rbegin();? ? ? while(rit != lst.rend())? ? ? ? ? std::cout << *rit++ << " ";? ? ? std::cout << std::endl;? ? ? ? // 使用base()實(shí)現(xiàn)insert或erase等操作。? ? ? std::vectorvect(a, a + sizeof(a)/sizeof(int));? ? ? // 反向迭代器指向2? ? ? std::vector::reverse_iterator vrit = std::find(vect.rbegin(), vect.rend(), 2);? ? ? // 注意:正向迭代器是指向3? ? ? std::vector::iterator it(vrit.base());? ? ? inserter(vect, it) = 10;? ? ? std::copy(vect.begin(), vect.end(), std::ostream_iterator(std::cout, " "));
std::cout?<<?std::endl;
}
輸出結(jié)果:
[cpp] view plain copy
print?
-2?-1?0?1?2?3?4
4?3?2?1?0?-1?-2
-2?-1?0?1?2?10?3?4
請(qǐng)按任意鍵繼續(xù).?.?.
作者:derivator
鏈接:http://www.itdecent.cn/p/f927e8a1b5be
來(lái)源:簡(jiǎn)書(shū)
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。