STL是C++中重要部分之一(面向?qū)ο蟆TL、模板等),其中三個(gè)基本的STL組件包括:
1. 迭代器。迭代器之于容器相當(dāng)于指針之于數(shù)組,提供了訪問容器對(duì)象的方法,事實(shí)上C++中的指針也是一種迭代器,但是要注意迭代器不僅僅是指針,不一定具有地址值。
2. 容器。容器是一種模板類,例如list、vector、deque等,一般由迭代器訪問容器中的數(shù)據(jù)。
3. 算法。STL中數(shù)據(jù)結(jié)構(gòu)和算法是分離的,各種函數(shù)在廣義容器中(包括鏈表、數(shù)組、string對(duì)象、容器)完全通用,只要支持相應(yīng)的迭代器即可。

1.頭文件:
STL頭文件一般不使用.h擴(kuò)展,其中主要使用的頭文件和對(duì)應(yīng)容器類如下:
#include Container Class
<deque>  deque
<list>  list
<map>  map, multimap
<queue>  queue, priority_queue
<set>  set, multiset
<stack>  stack
<vector>  vector
<string>  string
<iterator>  ***<***>::iterator
<algorithm>  各種算法函數(shù)
STL均使用標(biāo)準(zhǔn)命名空間using namespace std。

2.迭代器:
迭代器有五種類型,這五種類型是一種繼承關(guān)系,具體如下:
Input iterators:提供對(duì)數(shù)據(jù)的只讀訪問,前向推進(jìn)。輸入迭代器可以使用==和!=來測(cè)試是否相等;使用*來訪問數(shù)據(jù);使用++操作符前向推進(jìn)。例如find函數(shù)需要保證輸入迭代器。
Output iterators:提供對(duì)數(shù)據(jù)的只寫訪問,前向推進(jìn)。輸出迭代器缺省只寫,由于該迭代器無法讀取對(duì)象,因此不會(huì)在任何搜索和其他算法中使用它。
Forward iterators:提供讀寫訪問,前向推進(jìn)。例如replace函數(shù)需要保證前向迭代器。
Bidirectional iterators:提供讀寫訪問,前向或后向推進(jìn)。例如reverse函數(shù)需要保證雙向迭代器。
Random access iterators:提供讀寫訪問,隨機(jī)移動(dòng)(非const的指針也是隨機(jī)迭代器)。STL中的排序和搜索函數(shù)使用隨機(jī)訪問迭代器,隨機(jī)訪問迭代器可以使用關(guān)系操作符做比較。
除此之外,還包括一些特殊的迭代器:
指針迭代器:一個(gè)指針也是一種迭代器。
常量迭代器:對(duì)于只讀變量,為了防止錯(cuò)誤賦值,可以使用常量迭代器const_iterator,該迭代器指向的對(duì)象不允許改變。注意:const ***<***>::iterator的含義是該迭代器成為常量,不可指向其他數(shù)據(jù),與常量迭代器的含義是不一樣的。

3.流迭代器
將輸入輸出(例如標(biāo)準(zhǔn)輸入輸出流cin/cout或者文件流等)作為容器看待,因此接受迭代器參數(shù)的算法都可以和流一起工作。
STL定義模板類ostream_iterator作為輸出流迭代器,其構(gòu)造函數(shù)有兩個(gè)參數(shù),包括一個(gè)ostream對(duì)象和一個(gè)string值(作為間隔符),因此可以象下面一樣創(chuàng)建一個(gè)迭代器:
ostream_iterator<int> out(cout, “\t”)             //定義cout迭代器,可以和任何一個(gè)接受輸出迭代器的函數(shù)一起使用,如copy
copy(....., ......, out);
ofstream out(“text.txt”);
ostream_iterator<string> obegin(out, “\n”);       //定義文件流輸出迭代器
----------------------------------------
STL定義模板類istream_iterator作為輸入流迭代器,可指定讀取的來源,并應(yīng)該和結(jié)束迭代器比較。具體如下:
istream_iterator<int> intreader(cin);       //定義cin流迭代器,輸出結(jié)束用ctrl+Z+回車
isteam_iterator<int> eof;   //空的流迭代器表示結(jié)束
copy(istream_iterator<string>(cin), istream_iterator<string>(), 輸出迭代器);      //定義無變量名的cin流迭代器
ifstream in(“text.txt”);
istream_iterator<string> ibegin(in);
istream_iterator<string> iend;            //定義文件流輸入迭代器
還有一些具體應(yīng)用如下:

//利用流迭代器填充vector
{
    ifstream 
in("test.txt");
    istream_iterator
<string> ibegin(in);
    istream_iterator
<string> iend;
    vector
<string> vec(ibegin, iend);      //貌似會(huì)有問題,類型不匹配
    copy(vec.begin(), vec.end(), ostream_iterator<string>(cout, "\n"));
}

//利用輸入流填充vector
{
    vector
<string> vec;
    copy(istream_iterator
<string>(cin), istream_iterator<string>(), back_inserter(vec));
    sort(vec.begin(), vec.end());
    copy(vec.begin(), vec.end(), ostream_iterator
<string>(cout,"\n"));
}

//利用流迭代器保存vector內(nèi)容到文件
{
    ifstream 
in("test.txt");
    istream_iterator
<string> ibegin(in);
    istream_iterator
<string> iend;
    vector
<string> vec(ibegin, iend);
    ofstream 
out("testcopy.txt");
    copy(vec.begin(), vec.end(), ostream_iterator
<string>(out"\n"));    
}

注意:上面用輸入流迭代器來初始化vector后,不可再用這個(gè)輸入流迭代器,因?yàn)殡S著數(shù)據(jù)的讀取,迭代器已經(jīng)到達(dá)輸入流或者文件流的末尾了。

4.插入迭代器:
int arr[] = {1, 2, 3, 4, 5};
vector<int> vi;
copy(arr, arr + 5; vi.begin());
該語句不會(huì)執(zhí)行,因?yàn)闆]有為vi分配存儲(chǔ)空間。此時(shí)使用插入迭代器可以將值插入到容器中,自動(dòng)為vi擴(kuò)展存儲(chǔ)空間,主要包括三種插入迭代器。
普通插入器:將對(duì)象插入到容器任何對(duì)象的前面。該迭代器使用容器的insert操作符替代賦值運(yùn)算符,第一個(gè)參數(shù)是容器本身,第二個(gè)參數(shù)是容器迭代器指定插入位置。
Front inserters:將對(duì)象插入到數(shù)據(jù)集的前面,例如鏈表表頭。該迭代器使用push_front操作替代賦值運(yùn)算符,參數(shù)是容器本身。注意如vector沒有push_front的操作,所以不能使用front_inserter迭代器。
Back inserters:將對(duì)象插入到數(shù)據(jù)集的尾部,例如vector的尾部,導(dǎo)致vector容器擴(kuò)展。該迭代器調(diào)用容器的push_back操作替代賦值運(yùn)算符,參數(shù)是容器本身。
注意:使用插入迭代器可能導(dǎo)致容器中的其他對(duì)象移動(dòng)位置,因此現(xiàn)有的迭代器變成非法,需要重新賦值(list除外,不受影響)。

    int arr[] = {1, 2, 3, 4, 5};
list<int> vi;
copy(arr, arr + 5; front_inserter(vi));
//最終結(jié)果按序是5 4 3 2 1,因?yàn)槊看握{(diào)用push_front將一個(gè)數(shù)據(jù)插入到vi的前面
list<int>::iterator p = find(vi.begin(), vi.end(), 2);
copy(arr, arr + 2, inserter(vi, p));
//最終結(jié)果是5 4 3 1 2 2 1,因?yàn)檎{(diào)用insert一次性將所有數(shù)據(jù)插入到p前


5.混合迭代器函數(shù):
下面兩個(gè)迭代器函數(shù)非常有用:
advance(iterator, int):按照指定的數(shù)目增減迭代器,iterator改變。第一個(gè)參數(shù)是迭代器,第二個(gè)參數(shù)是增減的數(shù)目(前向迭代器該數(shù)必須為正,雙向或者隨機(jī)迭代器該數(shù)可以為負(fù))。
distance(iterator, iterator):返回到達(dá)一個(gè)迭代器所需遞增操作的數(shù)目,即兩個(gè)迭代器相差的距離。