C++沉思錄__迭代器介面卡
前文所述的5個主要的幾個迭代器,都是內置於於STL中的標準容器,用法也只能針對標準容器。STL在不斷的演變中,STL的愛好者擴充了迭代器的內容,他們在迭代器的基礎上發展而來,叫迭代器介面卡,他提供了更多的操作功能,也不僅僅侷限於容器,還可以應用於更多方面。正如容器有標準容器和容器介面卡,仿函式有標準仿函式和仿函式介面卡,這裡的迭代器介面卡也是一樣的道理。顯然他們都是在原有迭代器的基礎之上發展而來的,所以基礎迭代器擁有的他們都擁有。
這裡的難點在於如何理解“介面卡”,所謂的介面卡,我們可以通過下面的例子進行了解,先放結論:我們有一個需求,需要查詢陣列中最後一個值等於42的元素,對於已有的find函式和雙向迭代器來說,我們只能夠找到第一個值等於42的元素,而無法滿足要求,當然,在已有的資料結構的基礎上,我們可以重新編寫演算法,但是對於同樣一個數據結構,卻要用不同的演算法來解決,這不是我們想要的,這個時候,我們需要的是從後往前遍歷元素。這個時候,我們對原有的迭代器進行改造,使得改造後的迭代器能夠滿足原有演算法的需要。(用書上的話來說就是:我們原來有一個介面,但是這個介面不是我們想要的,我們就把已有類適配成所需要的介面)所謂的適配,就是對原有的迭代器進行改造,使其能夠用原有演算法實現不同的需求。“把已有類'適配'成所需要的介面“)。
舉例說明:對雙向迭代器改造後的迭代器介面卡,這是一種反向迭代器(正向迭代器)。顧名思義,反向迭代器會提供與普通迭代器相反方向的遍歷功能。反向迭代器其實一個正向迭代器的介面卡,它的實現都是通過呼叫正向迭代器的操作,為了與迭代器的概念保持一致(begin指向迭代器的第一個元素,end指向迭代器的最後一個元素的下一個位置),又與正向迭代器有一點點不同。reverse_iterator的實現中有一個名為current的Iterator,它是模板引數,即正向迭代器。正向迭代器指向的範圍是序列中的第一個元素到最後一個元素的下一個位置,為了保持迭代器概念的統一,反向迭代器的rbegin應該是序列的最後一個元素,rend應該是第一個元素前面的元素。
template<class It ,class T> class Rev { friend bool operator==(const Rev &x, const Rev &y) { return x.it == y.it; } friend bool operator!=(const Rev &x, const Rev &y) { return !(x.it == y.it); } public: Rev() { } Rev(It i):it(i) { } operator It()//型別轉換 遇到It就轉換成it { return it; } //將引數迭代器反向 Rev& operator++() { --it; return *this; } Rev operator--() { ++it; return *this; } Rev& operator++(int) { Rev r = *this; it++; return r; } Rev operator--(int) { Rev r = this; it--; return r; } T & operator*() { It i = it; return *--i; } private: It it; };
find實現
template<class P,class T>
P find(P start,P end,const T& x)
{
while(start !=end&& *start != x)
{
++start;
}
return start;
}
測試
typedef Rev<int * ,int> R;
int main(int argc, char const *argv[])
{
int x[100];
for(int i =0;i<100;i++)
{
x[i] =i+1;
}
int *p = find(x,x+100,42);
R r = find(R(x+100),R(x),42);
cout<<*r<<endl;//r本身是物件可以呼叫公用方法
cout<< *p<<endl;
system("pause");
return 0;
}