29. Knihovna standardnφch Üablon I
  1. Organizace ISO a ANSI se sna₧φ standardizovat programovacφ jazyk C++. Jednφm v²sledkem tΘto standardizace je Knihovna standardnφch Üablon (STL - pochßzφ od firmy Rogue Wave's). Jednß se o rozsßhlou knihovnu datov²ch struktur a algoritm∙.

  2. Hlavnφ Φßstφ STL je kolekce definicφ t°φd pro standardnφ datovΘ struktury a kolekce algoritm∙ pou₧φvan²ch k manipulaci s t∞mito strukturami. Struktura STL se liÜφ v mnoha ohledech od ostatnφch knihoven C++.
    Zßkladem pro pou₧itφ t°φd kontejner∙ a p°i°azen²ch algoritm∙ poskytnut²ch standardnφ knihovnou je koncepce iterßtor∙. Abstraktn∞, iterßtor je jednoduch² objekt, podobajφcφ se ukazateli, pou₧it² k prochßzenφ p°es vÜechny prvky ulo₧enΘ v kontejneru. Proto₧e v r∙zn²ch typech kontejner∙ se prochßzφ p°es prvky r∙zn²m zp∙sobem, jsou r∙znΘ typy iterßtor∙. Ka₧dß t°φda kontejneru ve standardnφ knihovn∞ m∙₧e generovat iterßtor s pot°ebnou funkΦnostφ pro uklßdacφ techniku pou₧itou p°i implementaci kontejneru.
    Stejn∞ jako ukazatelΘ mohou b²t v tradiΦnφm programovßnφ pou₧ity k r∙zn²m ·Φel∙m, takΘ iterßtory jsou pou₧φvßny pro mnoho r∙zn²ch Φinnostφ. Iterßtor m∙₧e b²t pou₧it k odkazovßnφ na specifickou hodnotu, stejn∞ jako ukazatel k odkazovßnφ na jistΘ mφsto pam∞ti. Na druhΘ stran∞ dvojice iterßtor∙ m∙₧e b²t pou₧ita k popisu rozsahu hodnot, stejn∞ jako dva ukazatelΘ mohou b²t pou₧ity k urΦenφ souvislΘ oblasti pam∞ti. V p°φpad∞ iterßtor∙ se ale nemusφ nutn∞ jednat o fyzickou sekvenci prvk∙, ale o logickou sekvenci, nebo¥ je zalo₧ena na typu kontejneru a prvky kontejneru jsou v po°adφ v jakΘm je kontejner udr₧uje.
    Normßlnφ ukazatelΘ mohou mφt n∞kdy hodnotu null, co₧ znamenß, ₧e na nic neukazujφ. Iterßtory takΘ nemusφ urΦovat specifickou hodnotu. Jako je chyba dereferencovat ukazatel s hodnotou null je takΘ chybou dereferencovat iterßtor, kter² neurΦuje hodnotu.
    Kdy₧ dva ukazatelΘ popisujφ oblast v pam∞ti jsou pou₧ity v programu C++, pak koncov² ukazatel m∙₧e ukazovat na mφsto, kterΘ ji₧ nemusφ pat°it do oblasti. Nap°. pole nazvanΘ x o dΘlce 10 prvk∙ m∙₧e b²t n∞kdy popisovßno jako rozÜφ°enφ od x do x+10, i kdy₧ prvek x+10 ji₧ nenφ souΦßstφ pole (ukazuje na hodnotu ulo₧enou za polem). K popisu rozsahu se podobn∞ pou₧φvajφ i iterßtory. Druh² iterßtor takΘ urΦuje nßsledujφcφ hodnotu v sekvenci za rozsahem. Nenφ vhodnΘ ale dereferencovat iterßtor, kter² je pou₧it ke specifikaci konce rozsahu (m∙₧e to b²t indikace koncovΘ hodnoty).
    Stejn∞ jako u normßlnφch ukazatel∙, zßkladnφ operace pou₧φvanß k modifikaci iterßtoru je operace inkrementace (operßtor ++). Kdy₧ operßtor inkrementace je aplikovßn na iterßtor, kter² ukazuje na poslednφ hodnotu v sekvenci, pak je zm∞n∞n na indikaci koncovΘ hodnoty.
    Ve standardnφ knihovn∞ je pou₧φvßno p∞t zßkladnφch tvar∙ iterßtor∙: Kategorie iterßtor∙ jsou hierarchickΘ. Dop°edn² iterßtor m∙₧e b²t pou₧it, kdy₧ jsou po₧adovßny vstupnφ nebo v²stupnφ iterßtory, obousm∞rn² iterßtor m∙₧e b²t pou₧it namφsto dop°ednΘho iterßtoru a iterßtor nßhodnΘho p°φstupu m∙₧e b²t pou₧it v situacφch vy₧adujφcφch obousm∞rnost.
    Druhou charakteristikou iterßtoru je to, zda m∙₧e b²t pou₧it k modifikaci hodnot ulo₧en²ch v p°i°azenΘm kontejneru. Konstantnφ iterßtor je ten, kter² m∙₧e b²t pou₧it pouze pro p°φstup, ale ne pro modifikaci. V²stupnφ iterßtory nejsou nikdy konstantnφ a vstupnφ iterßtory jsou konstantnφ v₧dy. Ostatnφ iterßtory mohou, ale nemusφ b²t konstantnφ, zßvisφ to na tom, jak jsou vytvo°eny. Je tedy konstantnφ a nekonstantnφ obousm∞rn² iterßtor, konstantnφ a nekonstantnφ iterßtor nßhodnΘho p°φstupu atd.
  3. Vstupnφ iterßtory jsou nejjednoduÜÜφm tvarem iterßtoru. K pochopenφ jejich mo₧nostφ p°edpoklßdejme p°φklad programu. Obecn² algoritmus find (bude podrobn∞ popsßn pozd∞ji) provßdφ jednoduchΘ lineßrnφ hledßnφ specifikovanΘ hodnoty v kontejneru. Obsah kontejneru je popsßn pomocφ dvou iterßtor∙, kterΘ se jmenujφ first a last. Dokud first nenφ roven last, pak prvek urΦen² first je porovnßvßn s testovanou hodnotou. P°i rovnosti je vrßcen iterßtor, kter² nynφ ukazuje na nalezen² prvek. P°i nerovnosti, iterßtor first je inkrementovßn a cyklus pokraΦuje. Pokud je prohledßna celß oblast pam∞ti bez nalezenφ po₧adovanΘ hodnoty, pak algoritmus vracφ koncovou hodnotu.

  4. template <class InputIterator, class T>
    InputIterator
       find (InputIterator first, InputIterator last, const T& value)
    {
       while (first != last && *first != value)
          ++first;
       return first;
    }
    Tento algoritmus ukazuje t°i po₧adavky na vstupnφ iterßror: Vstupnφ iterßtory majφ t°i hlavnφ varianty:
  5. V²stupnφ iterßtor mß opaΦnou funkci ne₧ vstupnφ iterßtor. V²stupnφ iterßtory mohou b²t pou₧φvßny k p°i°azovßnφ hodnot do sekvencφ, ale nemohou b²t pou₧φvßny k zp°φstupn∞nφ hodnot. Nap°. v²stupnφ iterßtor m∙₧eme pou₧φt v obecnΘm algoritmu, kter² kopφruje hodnoty z jednΘ sekvence do jinΘ:

  6. template <class InputIterator, class OutputIterator>
    OutputIterator copy
       (InputIterator first, InputIterator last, OutputIterator result)
    {
        while (first != last)
          *result++ = *first++;
        return result;
    }
    Rozsah zdrojov²ch hodnot je specifikovßn pßrem vstupnφch iterßtor∙ a cφl v²stupnφm iterßtorem (p°edpoklßdßme, ₧e obsahuje stejnΘ mno₧stvφ hodnot, jako rozsah zdrojov²ch hodnot). Jak ukazuje tento algoritmus, v²stupnφ iterßtor m∙₧e modifikovat prvek na kter² ukazuje a m∙₧e b²t tedy pou₧it jako cφl pro p°i°azenφ. V²stupnφ iterßtory mohou b²t dereferencovßny pouze tφmto zp∙sobem a nemohou b²t pou₧ity pro p°φstup k prvk∙m, na kterΘ ukazujφ.
    Jak je uvedeno v²Üe, normßlnφ ukazatele, stejn∞ jako vÜechny iterßtory vytvo°enΘ kontejnery ve standardnφ knihovn∞, mohou b²t pou₧ity jako v²stupnφ iterßtory. Nßsledujφcφ Φßst k≤du kopφruje prvky z pole typu C do standardnφho typu vector:
    int data[100];
    vector<int> newdata(100);
       ...
    copy (data, data+100, newdata.begin());
    Stejn∞ jako istream_iterator nabφzφ mo₧nost operovßnφ na vstupnφm proudu pomocφ mechanismu vstupnφho iterßtoru, ostream_iterator umo₧≥uje zapisovat hodnoty do v²stupnφho proudu.
    Jin²m tvarem v²stupnφho operßtoru je vklßdacφ iterßtor. Vklßdacφ iterßtor zm∞nφ operace v²stupu na vklßdßnφ do kontejneru. To umo₧≥uje pou₧φvßnφ operace typu kopφrovßnφ s kontejnery prom∞nnΘ dΘlky, jako jsou seznamy a mno₧iny.
  7. Dop°edn² iterßtor kombinuje slu₧by vstupnφho iterßtoru a v²stupnφho iterßtoru. Umo₧≥uje p°istupovat k hodnotßm i modifikovat hodnoty. Jednou z funkcφ kterou pou₧φvß dop°edn² iterßtor je algoritmus replace, kter² nahrazuje v²skyty specifikovan²ch hodnot jin²mi hodnotami. Tento algoritmus je zapsßn takto:

  8. template <class ForwardIterator, class T>
    void
       replace (ForwardIterator first, ForwardIterator last,
                const T& old_value, const T& new_value)
    {
        while (first != last)
        {
        if (*first == old_value)
            *first = new_value;
            ++first;
        }
    }
    B∞₧n² ukazatel, stejn∞ jako libovoln² z iterßtor∙ vytvß°en² kontejnery ve standardnφ knihovn∞, m∙₧e b²t pou₧it jako dop°edn² iterßtor. Nap°. nßsleduje nahrazenφ instancφ hodnot 7 hodnotami 11 ve vektoru cel²ch Φφsel:
    replace (aVec.begin(), aVec.end(), 7, 11);
  9. Obousm∞rnΘ iterßtory se podobajφ dop°edn²m iterßtor∙m, s tou odchylkou, ₧e obousm∞rnΘ iterßtory podporujφ operßtor dekrementace (operßtor --). To umo₧≥uje pohyby dop°edu a zp∞t po prvcφch kontejneru. Obousm∞rn² iterßtor m∙₧eme pou₧φt nap°. ve funkci, kterß obracφ hodnoty kontejneru a umis¥uje v²sledek do novΘho kontejneru.

  10. template <class BidirectionalIterator, class OutputIterator>
    OutputIterator
       reverse_copy (BidirectionalIterator first, BidirectionalIterator last,
                     OutputIterator result)
    {
        while (first != last)
        *result++ = *--last;
        return result;
    }
    Jako v₧dy, hodnota p∙vodn∞ urΦenß parametrem last ji₧ nepat°φ do kontejneru.
    Funkce reverse_copy m∙₧e b²t nap°. pou₧ita k obracenφ hodnot z°et∞zenΘho seznamu a umφst∞nφ v²sledku do vektoru:
    list<int> aList;
    ....
    vector<int> aVec (aList.size());
    reverse_copy (aList.begin(), aList.end(), aVec.begin() );
  11. N∞kterΘ algoritmy vy₧adujφ v∞tÜφ schopnosti ne₧ mo₧nost p°istupovat k hodnotßm ve sm∞ru dop°edu nebo dozadu. Iterßtory nßhodnΘho p°φstupu poskytujφ hodnoty pro p°φstup nßhodn∞, podobn∞ jako normßlnφ ukazatelΘ. Kdy₧ pou₧φvßme normßlnφ ukazatele, pak aritmetickΘ operace mohou b²t pou₧ity k urΦenφ adresy pam∞ti; tj. x+10 je pam∞¥ 10 prvk∙ od zaΦßtku x. S iterßtory logick² v²znam je stejn² (x+10 je desßt² prvek za x), ale fyzickß adresa se m∙₧e liÜit.

  12. Algoritmy, kterΘ pou₧φvajφ nßhodnΘ p°φstupovΘ iterßtory zahrnujφ obecnΘ operace jako je °azenφ a binßrnφ vyhledßvßnφ. Nap°. nßsledujφcφ algoritmus nßhodn∞ zamφchß prvky kontejneru. Podobß se (ale je jednoduÜÜφ) funkci random_shuffle ze standardnφ knihovny:
    template <class RandomAccessIterator>
    void
       mixup (RandomAccessIterator first, RandomAccessIterator last)
    {
       while (first < last)
       {
          iter_swap(first, first + randomInteger(last - first));
          ++first;
       }
    }
    Program prochßzφ od pozice urΦenΘ first, kterß je d°φve v sekvenci ne₧ pozice last. Pouze iterßtory nßhodnΘho p°φstupu mohou b²t porovnßvßny pomocφ relaΦnφch operßtor∙; vÜechny ostatnφ iterßtory mohou b²t porovnßvßny pouze na rovnost nebo nerovnost. P°i ka₧dΘm pr∙chodu cyklem, v²raz last - first urΦuje poΦet prvk∙ mezi dv∞mi mezemi. Funkce randomInteger je urΦena pro generovßnφ nßhodn²ch Φφsel mezi 0 a hodnotou parametru. Pomocφ standardnφho generßtoru nßhodn²ch Φφsel tuto funkci m∙₧eme zadat takto:
    unsigned int randomInteger (unsigned int n)
    {
       return rand() % n;
    }
    Tato nßhodnß hodnota je p°iΦtena k iterßtoru first, co₧ zp∙sobφ, ₧e iterßtor nßhodn∞ vybφrß hodnotu v kontejneru. Tato hodnota je potom vym∞n∞na s prvkem na kter² ukazuje iterßtor first.
  13. Iterßtory p°irozen∞ dodr₧ujφ po°adφ hodnot p°ipojenΘho kontejneru. Pro typy vector nebo map po°adφ je dßno zv∞tÜujφcφmi se hodnotami indexu. Pro set je to zv∞tÜujφcφ se hodnota prvk∙ dr₧en²ch v kontejneru. Pro list po°adφ je explicitn∞ odvozeno od zp∙sobu vklßdßnφ hodnot.

  14. Reverznφ iterßtory poskytujφ hodnoty p°esn∞ v opaΦnΘm po°adφ ne₧ standardnφ iterßtory. Tj. pro vector nebo list reverznφ iterßtor bude generovat poslednφ prvek prvnφ a prvnφ prvek poslednφ. Pro set je nejv∞tÜφ prvek generovßn prvnφ a nejmenÜφ poslednφ. Reverznφ iterßtory tedy netvo°φ novou kategorii iterßtor∙. Jsou reverznφ obousm∞rnΘ iterßtory, reverznφ iterßtory nßhodnΘho p°φstupu, atd.
    DatovΘ typy list, set a map poskytujφ dvojice metod, kterΘ vytvß°ejφ reverznφ obousm∞rnΘ iterßtory. Funkce rbegin a rend generujφ iterßtory, kterΘ prochßzejφ p°ipojen²m kontejnerem v opaΦnΘm po°adφ. Inkrementace p°esouvß iterßtor zp∞t a dekrementace dop°edu. Podobn∞ datovΘ typy vector a deque poskytujφ funkce (takΘ se jmenujφ rbegin a rend), kterΘ vytvß°ejφ reverznφ iterßtory nßhodnΘho p°φstupu. Operßtor sΦφtßnφ stejn∞ jako inkrementace p°esouvß iterßtor zp∞t v sekvenci.
  15. ProudovΘ iterßtory jsou pou₧φvßny pro p°φstup k existujφcφmu vstupnφmu nebo v²stupnφmu datovΘmu proudu pomocφ operacφ iterßtoru.

  16. Jak ji₧ bylo uvedeno u popisu vstupnφch iterßtor∙, standardnφ knihovna poskytuje mechanismus k zapojenφ vstupnφho proudu do vstupnφho iterßtoru. Tato schopnost je poskytnuta t°φdou istream_iterator.  P°i deklaraci, Φty°i parametry Üablony jsou typ prvku, typ znakovΘho proudu, typ rysu znaku a typ vzdßlenosti mezi prvky. Poslednφ dva parametry majφ implicitnφ hodnoty: char_traits<charT > a ptrdiff_t. To obvykle zajistφ vyhovujφcφ chovßnφ. Jeden parametr poskytnut² konstruktoru pro istream_iterator je zp°φstup≥ovan² proud. P°i ka₧dΘm pou₧itφ operßtoru ++ na iterßtor vstupnφho proudu je p°eΦtena a ulo₧ena novß hodnota z proudu (pomocφ operßtoru >>). Tato hodnota je pak dostupnß pomocφ operßtoru dereference (operßtor *). Hodnota vytvo°enß istream_iterator, kdy₧ nenφ poskytnut konstruktoru ₧ßdn² parametr, m∙₧e b²t pou₧ita jako koncovß hodnota iterßtoru. Nap°. nßsledujφcφ k≤d hledß prvnφ hodnotu 7 v souboru cel²ch Φφsel.
    istream_iterator<int, char> intstream(cin), eof;
    istream_iterator<int, char>::iterator where = find(intstream, eof, 7);
    Prvek urΦen² iterßtorem pro vstupnφ proud je p°φstupn² pouze, dokud nenφ po₧adovßn nßsledujφcφ prvek v proudu. Proto₧e iterßtor vstupnφho proudu je vstupnφ iterßtor, prvky mohou b²t pouze zp°φstup≥ovßny a nelze je modifikovat p°i°azenφm. Prvky mohou b²t zp°φstupn∞ny pouze jednou a to pouze sm∞rem dop°edu. Pokud pot°ebujeme Φφst obsah proudu n∞kolikrßt, pak pro ka₧d² pr∙chod musφme vytvo°it samostatn² iterßtor.
    Mechanismus iterßtoru v²stupnφho proudu je analogick² iterßtoru vstupnφho proudu. P°i ka₧dΘm p°i°azenφ hodnoty iterßtoru, je takΘ hodnota zapsßna do p°i°azenΘho v²stupnΘho proudu pomocφ operßtoru  >>. K vytvo°enφ iterßtoru v²stupnφho proudu musφme specifikovat jako parametr v konstruktoru p°i°azovan² v²stupnφ proud. Hodnoty zapisovanΘ do v²stupnφho proudu musφ vyhovovat operaci >> proudu. Voliteln² druh² parametr konstruktoru je °et∞zec, kter² bude pou₧it jako odd∞lovaΦ mezi ka₧dou dvojicφ hodnot. Nap°. nßsledujφcφ k≤d kopφruje vÜechny hodnoty z vektoru na standardnφ v²stup a odd∞luje hodnoty mezerami:
    copy(newdata.begin(),newdata.end(),ostream_iterator<int,char>(cout," "));
    Algoritmus jednoduchΘ transformace souboru m∙₧e b²t vytvo°en kombinacφ iterßtor∙ vstupnφho a v²stupnφho proudu a r∙zn²ch algoritm∙ poskytnut²ch standardnφ knihovnou. Nßsledujφcφ krßtk² program Φte soubor cel²ch Φφsel ze standardnφho vstupu, odstra≥uje vÜechny v²skyty hodnot 7 a zbytek kopφruje na standardnφ v²stup (ka₧dß hodnota je odd∞lena od°ßdkovßnφm):
    void main()
    {
       istream_iterator<int, char> input (cin), eof;
       ostream_iterator<int, char> output (cout, "\n");
       remove_copy (input, eof, output, 7);
    }
  17. P°i°azovßnφ dereferencovanΘ hodnot∞ v²stupnφho iterßtoru je normßln∞ pou₧ito pro p°epsßnφ obsahu existujφcφho mφsta. Nap°. nßsledujφcφ vyvolßnφ funkce copy p°enese hodnoty z jednoho vektoru do jinΘho, i kdy₧ mφsto pro druh² vektor je ji₧ vytvo°eno (a p°φpadn∞ inicializovßno):

  18. vector<int> a(10);
    vector<int> b(10);
       ...
    copy (a.begin(), a.end(), b.begin());
    Tφmto zp∙sobem mohou b²t p°episovßny i struktury jako jsou seznamy. Nßsledujφcφ p°φklad p°edpoklßdß, ₧e seznam nazvan² c mß alespo≥ 10 prvk∙. PoΦßteΦnφch 10 mφst v seznamu c bude nahrazeno obsahem vektoru a:
    list<int> c;
       ...
    copy (a.begin(), a.end(), c.begin());
    U struktur jako jsou seznamy a mno₧iny, kterΘ se dynamicky p°i p°idßnφ novΘho prvku zv∞tÜujφ, je ΦastΘ vlo₧enφ novΘ hodnoty do struktury mφsto p°epsßnφ existujφcφho prvku. P°i pou₧itφ vklßdacφho iterßtoru jsou prvky do p°i°azenΘho kontejneru vklßdßny (mφsto p°episovßnφ prvk∙ v kontejneru). V²stupnφ operace iterßtoru je zm∞n∞na na vklßdßnφ do p°i°azenΘho kontejneru. Nßsledujφcφ p°φklad nap°. vklßdß hodnoty vektoru do p∙vodn∞ prßzdnΘho seznamu:
    list<int> d;
    copy (a.begin(), a.end(), front_inserter(d));
    Jsou t°i tvary vklßdacφch iterßtor∙ (vÜechny mohou b²t pou₧ity ke zm∞n∞ kopφrovacφ operace na vklßdacφ operaci). Iterßtor generovan² pomocφ front_inserter (pou₧it² v²Üe) vklßdß prvek do Φela kontejneru. Iterßtor generovan² back_inserter umφs¥uje prvek na konec do kontejneru. Oba tvary mohou b²t pou₧ity pro typy list a deque, ale ne s mno₧inami a mapovßnφm. back_inserter, ale ne front_inserter, m∙₧e b²t pou₧it i s vektorem. T°etφ nejobecn∞jÜφ tvar je inserter, p°ebφrß dva parametry (kontejner a iterßtor v kontejneru). Tento tvar kopφruje prvky na specifikovanΘ mφsto v kontejneru (pro seznam to znamenß, ₧e prvky jsou kopφrovßny bezprost°edn∞ p°ed specifikovanou pozici). Tento tvar m∙₧e b²t pou₧it se vÜemi strukturami, pro kterΘ pracujφ p°edchozφ dva tvary a takΘ s mno₧inami a mapovßnφm.
    Nßsledujφcφ jednoduch² program ukazuje pou₧itφ vÜech t°φ tvar∙ vklßdacφch operßtor∙. Nejprve hodnoty 3, 2, a 1 jsou vlo₧eny do Φela prßzdnΘho seznamu. PovÜimn∞te si jak jsou vklßdßny; ka₧dß je vlo₧ena na nov∞ vytvo°en² zaΦßtek, a tak zφskßme v²slednΘ po°adφ 1, 2, 3. Dßle hodnoty 7, 8 a 9 jsou vlo₧eny na konec seznamu. Nakonec operaci find pou₧ijeme k umφst∞nφ iterßtoru na hodnotu 7 a bezprost°edn∞ p°ed nφ vlo₧φme Φφsla 4, 5 a 6. V²sledkem je seznam Φφsel v po°adφ od 1 do 9.
    void main() {
       int threeToOne [ ] = {3, 2, 1};
       int fourToSix [ ] = {4, 5, 6};
       int sevenToNine [ ] = {7, 8, 9};
       list<int> aList;
       copy (threeToOne, threeToOne+3, front_inserter(aList));
       copy (sevenToNine, sevenToNine+3, back_inserter(aList));
       list<int>::iterator seven = find(aList.begin(), aList.end(), 7);
       copy (fourToSix, fourToSix+3, inserter(aList, seven));
       copy (aList.begin(),aList.end(),ostream_iterator<int,char>(cout," "));
       cout << endl;
    }
    PovÜimn∞te si d∙le₧itΘho rozdφlu mezi iterßtory vytvo°en²mi inserter(aList, aList.begin()) a front_inserter(aList). Volßnφ prvnφho kopφruje hodnoty v po°adφ, p°idßvß ka₧d² z nich na zaΦßtek seznamu, zatφmco p°i pou₧itφ druhΘho je ka₧dß hodnota p°ekopφrovßna na nov² zaΦßtek. V²sledkem je to, ₧e front_inserter(aList) obracφ po°adφ p∙vodnφ sekvence, zatφmco inserter(aList, aList.begin()) zachovßvß p∙vodnφ po°adφ.
  19. Standardnφ knihovna poskytuje dv∞ funkce, kterΘ mohou b²t pou₧ity pro manipulaci s iterßtory. Funkce advance p°ebφrß jako parametry iterßtor a Φφselnou hodnotu a modifikuje iterßtor p°esunem o zadanou vzdßlenost (Φφselnou hodnotu).

  20. void advance (InputIterator & iter, Distance & n);
    Pro iterßtory nßhodnΘho p°φstupu je to stejnΘ jako iter + n; nicmΘn∞ funkce je u₧iteΦnß, proto₧e operuje se vÜemi tvary iterßtor∙. Pro dop°ednΘ iterßtory Distance musφ b²t kladnß, zatφmco pro iterßtory obousm∞rnΘ a s nßhodn²m p°φstupem m∙₧e b²t kladnß i zßpornß. Funkce netestuje p°φpustnost operace na p°ipojenΘm iterßtoru.
    Druhß funkce distance vracφ poΦet operacφ iterßtoru nutn²ch k p°esunu z jednoho prvku v sekvenci na jin². Popis funkce je:
    void distance(InputIterator first, InputIterator last, Distance &n);
    V²sledek je vracen ve t°etφm parametru, kter² je p°edan² odkazem. Je to hodnota urΦujφcφ, kolikrßt musφ b²t pou₧it operßtor ++ pro p°esun z first na last. Musφme se ujistit, ₧e prom∞nnß p°edanß tomuto parametru je p°ed vyvolßnφm funkce sprßvn∞ inicializovanß.

  21. N∞kterΘ algoritmy poskytnutΘ standardnφ knihovnou vy₧adujφ jako parametry funkce. Jednoduch²m p°φkladem je algoritmus for_each, kter² vyvolßvß funkci p°edanou jako parametr pro ka₧dou hodnotu dr₧enou v kontejneru. Nßsledujφcφ k≤d nap°. aplikuje funkci printElement k vytvo°enφ v²stupu popisujφcφho vÜechny prvky v seznamu celoΦφseln²ch hodnot:

  22. void printElement (int value)
    {
       cout << "Seznam obsahuje " << value << endl;
    }
    main ()
    {
       list<int> aList;
          ...
       for_each (aList.begin(), aList.end(), printElement);
    }
    Binßrnφ funkce p°ebφrajφ dva parametry a jsou Φasto aplikovßny na hodnoty ze dvou r∙zn²ch sekvencφ. P°edpoklßdejme nap°. ₧e mßme seznam °et∞zc∙ a seznam cel²ch Φφsel. Pro ka₧d² prvek v prvnφm seznamu chceme replikovat °et∞zec tolikrßt, kolik udßvß odpovφdajφcφ hodnota ve druhΘm seznamu. Tuto snadnou operaci m∙₧eme provΘst pomocφ funkce transform ze standardnφ knihovny. Nejprve definujeme binßrnφ funkci s popsan²mi charakteristikami:
    string stringRepeat (const string & base, int number)
    {
       string result;   // p∙vodn∞ prßzdn² °et∞zec
       while (number--)  result += base;
       return result;
    }
    Nßsledujφcφ volßnφ transform pak vytvß°φ po₧adovan² efekt:
    list<string> words;
    list<int> counts;
       ...
    transform (words.begin(), words.end(),
       counts.begin(), words.begin(), stringRepeat);
    Transformovßnφm slov one, two, three s hodnotami 3, 2, 3 dostaneme v²sledek oneoneone, twotwo, threethreethree.
  23. Tvrzenφ jsou jednoduchΘ funkce, kterΘ vracejφ logickou nebo celoΦφselnou hodnotu (true je nenula a false nula). Nßsledujφcφ funkce p°ebφrß celΘ Φφslo a vracφ true pokud Φφslo reprezentuje p°estupn² rok a false v opaΦnΘm p°φpad∞:

  24. bool isLeapYear (unsigned int year)
    {
       if (0 == year % 400) return true;
       if (0 == year % 100) return false;
       if (0 == year % 4) return true;
       return false;
    }
    Tvrzenφ se pou₧φvajφ jako parametry, nap°. v obecnΘm algoritmu find_if. Tento algoritmus vracφ prvnφ hodnotu, kterß spl≥uje tvrzenφ nebo koncovou hodnotu, pokud prvek nebyl nalezen. Pomocφ tohoto algoritmu nalezneme prvnφ p°estupn² rok v seznamu rok∙:
    list<int>::iterator firstLeap=find_if(aList.begin(),aList.end(),isLeapYear);
  25. Objekt funkce je instance t°φdy, kterß definuje zßvorkov² operßtor jako metodu. Je mnoho situacφ, kde lze pou₧φt objekt funkce na mφst∞ funkce. Kdy₧ je pou₧it objekt funkce jako funkce, pak mφsto volßnφ funkce je pou₧it zßvorkov² operßtor. Abychom si to mohli ukßzat, p°edpoklßdejme nßsledujφcφ definici t°φdy:

  26. class biggerThanThree {
     public:
       bool operator () (int val) { return val > 3; }
    };
    Jestli₧e vytvo°φme instanci t°φdy biggerThanThree, pak poka₧dΘ kdy₧ se odkazujeme na tento objekt pomocφ syntaxe volßnφ funkce, je vyvolßna metoda zßvorkovΘho operßtoru. Nßsledujφcφm krokem je zobecn∞nφ tΘto t°φdy p°idßnφm konstruktoru a konstantnφ datovΘ polo₧ky, kterß je konstruktorem nastavena.
    class biggerThan {
       public:
          const int testValue;
          biggerThan (int x) : testValue(x) { }
          bool operator () (int val) { return val > testValue; }
    };
    V²sledkem je obecnΘ "v∞tÜφ ne₧ X", kde hodnota X je urΦena p°i vytvß°enφ instance t°φdy. Nßsledujφcφ p°φklad nap°. hledß prvnφ hodnotu v seznamu, kterß je v∞tÜφ ne₧ 12:
    list<int>::iterator firstBig =
        find_if (aList.begin(), aList.end(), biggerThan(12));
    T°i nejobecn∞jÜφ d∙vody pro pou₧φvßnφ objekt∙ funkcφ na mφst∞ normßlnφch funkcφ jsou vyu₧itφ existujφcφho objektu funkce poskytnutΘho standardnφ knihovnou mφsto novΘ funkce, vyvolßnφ provßd∞nΘ pomocφ vno°enΘ funkce a umo₧n∞nφ objektu funkce zp°φstup≥ovat nebo nastavovat stavovΘ informace dr₧enΘ objektem. Pozd∞ji se seznßmφme s p°φklady.
    Nßsledujφcφ tabulka ukazuje objekty funkcφ poskytnutΘ standardnφ knihovnou.
     
    JmΘno
    Implementovanß operace
    AritmetickΘ funkce
    plus sΦφtßnφ x + y
    minus odeΦφtßnφ x - y
    multiplies nßsobenφ x * y
    divides d∞lenφ x / y
    modulus zbytek po d∞lenφ x % y
    negate negace - x
    Porovnßvacφ funkce
    equal_to test rovnosti x == y
    not_equal_to test nerovnosti x != y
    greater v∞tÜφ x > y
    less menÜφ x < y
    greater_equal v∞tÜφ nebo rovno x >= y
    less_equal  menÜφ nebo rovno x <= y
    LogickΘ funkce
    logical_and logick² souΦin x && y
    logical_or logick² souΦet x || y
    logical_not logickß negace ! x

    Nßsleduje °ada p°φklad∙, kterΘ ukazujφ pou₧φvßnφ objekt∙ funkcφ. Prvnφ p°φklad pou₧φvß plus pro v²poΦet souΦt∙ dvou seznam∙ cel²ch Φφsel po prvcφch a umφst∞nφ v²sledk∙ zp∞t do prvnφho seznamu. To m∙₧e b²t provedeno takto:
    transform (listOne.begin(), listOne.end(), listTwo.begin(),
       listOne.begin(), plus<int>() );
    Druh² p°φklad neguje ka₧d² prvek ve vektoru logick²ch hodnot:
    transform (aVec.begin(), aVec.end(), aVec.begin(), logical_not<bool>() );
    Zßkladnφ t°φdy pou₧itΘ standardnφ knihovnou v definicφch funkcφ uveden²ch v p°edchozφ tabulce jsou dostupnΘ pro vytvß°enφ nov²ch objekt∙ unßrnφch a binßrnφch funkcφ. Zßkladnφ t°φdy jsou definovßny takto:
    template <class Arg, class Result>
    struct unary_function {
       typedef Arg argument_type;
       typedef Result result_type;
    };
    template <class Arg1, class Arg2, class Result>
    struct binary_function {
       typedef Arg1 first_argument_type;
       typedef Arg2 second_argument_type;
       typedef Result result_type;
    };
    Chceme nap°. p°evzφt binßrnφ funkcφ parametr typu Widget a celΘ Φφslo a porovnat identifikaΦnφ Φφslo "widgetu" s p°edanou hodnotou. Funkci, kterß toto provßdφ zapφÜeme takto:
    struct WidgetTester : binary_function<Widget, int, bool> {
    public:
       bool operator () (const Widget & wid, int testid) const
          { return wid.id == testid; }
    };
    Druh²m d∙vodem pro pou₧φvßnφ objekt∙ funkcφ namφsto funkcφ je rychlejÜφ k≤d. V mnoha p°φpadech vyvolßnφ objektu funkce, jako je p°φklad volßnφ funkce transform uveden² v²Üe, m∙₧e b²t provedeno jako vlo₧enß funkce, co₧ eliminuje volßnφ p°ekrytΘ funkce.
    T°etφm hlavnφm d∙vodem pou₧itφ objektu funkce na mφst∞ funkce je to, ₧e ka₧dΘ volßnφ m∙₧e zjistit n∞jak² stav nastaven² p°edchozφm volßnφm. P°φkladem je vytvß°enφ generßtoru pou₧itΘho v obecnΘm algoritmu generate. Generßtor je jednoduchß funkce, kterß vracφ p°i ka₧dΘm vyvolßnφ jinou hodnotu. ╚asto pou₧φvan²m tvarem generßtoru je generßtor nßhodn²ch Φφsel, ale jsou takΘ jinß pou₧itφ pro tuto koncepci. SekvenΦnφ generßtor jednoduÜe vracφ hodnoty zv∞tÜujφcφ se sekvence cel²ch Φφsel (1, 2, 3, 4 atd.). Toto provßdφ t°φda iotaGen, kterß je definovßna takto:
    class iotaGen {
    public:
       iotaGen (int start = 0) : current(start) { }
       int operator () () { return current++; }
    private:
       int current;
    };
    Objekt udr₧uje souΦasnou hodnotu, kterß m∙₧e b²t nastavena konstruktorem (nebo implicitn∞ na 0). Poka₧dΘ kdy₧ je pou₧it operßtor funkΦnφho volßnφ, pak je vrßcena souΦasnß hodnota a je takΘ inkrementovßna. Pomocφ tohoto objektu v nßsledujφcφm volßnφ standardnφ knihovnφ funkce generate inicializujeme vektor 20 prvk∙ hodnotami 1 a₧ 20:
    vector<int> aVec(20);
    generate (aVec.begin(), aVec.end(), iotaGen(1));

  27. FunkΦnφ adaptΘr je instance t°φdy, kterß adaptuje globßlnφ funkci nebo metodu tak, ₧e funkce m∙₧e b²t pou₧ita jako objekt funkce (funkΦnφ adaptΘry mohou b²t takΘ pou₧ity ke zm∞n∞ chovßnφ funkce nebo objektu funkce). Ka₧d² funkΦnφ adaptΘr poskytuje konstruktor, kter² p°ebφrß globßlnφ funkci nebo metodu. AdaptΘr takΘ poskytuje zßvorkov² operßtor, kter² sm∞ruje svΘ volßnφ na tuto p°i°azenou globßlnφ funkci nebo metodu.

  28. èablony pointer_to_unary_function a pointer_to_binary_function adaptujφ jedno nebo dvou parametrovΘ globßlnφ funkce. Tyto adaptΘry mohou b²t aplikovßny p°φmo nebo m∙₧eme pou₧φt Üablonu funkce ptr_fun k vytvo°enφ p°φsluÜnΘho adaptΘru automaticky. Nap°. m∙₧eme adaptovat jednoduchou funkci times3 a aplikovat ji na vektor cel²ch Φφsel takto:
    int times3(int x) {
      return 3*x;
    }
    int a[] = {1,2,3,4,5};
    vector<int> v(a,a+5), v2;
    transform(v.begin(),v.end(),v2.end(),ptr_fun(times3));
    P°φpadn∞ m∙₧eme aplikovat adaptΘr, a pak p°edat nov² adaptovan² objekt funkce vektoru.
    pointer_to_unary_function<int,int> pf(times3);
    transform(v.begin(),v.end(),v2.end(),pf);
    Rodina Üablon mem_fun adaptuje metody mφsto globßlnφch funkcφ. Nap°. pokud mßme mno₧inu seznam∙ a chceme ka₧d² seznam z mno₧iny se°adit, pak m∙₧eme pou₧φt mem_fun_t (nebo jednoduÜÜφ mem_fun) k aplikovßnφ metody °azenφ seznamu na ka₧d² prvek v mno₧in∞.
    set<list<int>* > s;
    // Inicializace mno₧iny seznamy
    à
    // Se°azenφ ka₧dΘho seznamu v mno₧in∞.
    for_each(s.begin(),s.end(),mem_fun(&list<int>::sort));
    To je nezbytnΘ, nebo¥ obecn² °adφcφ algoritmus nem∙₧e b²t pou₧it pro seznam. Je to takΘ nejjednoduÜÜφ zp∙sob p°φstupu k libovoln²m polymorfick²m charakteristikßm objekt∙ dr₧en²ch ve standardnφm kontejneru. Nap°. m∙₧eme vyvolat virtußlnφ kreslφcφ funkce na kolekci objekt∙, kterΘ jsou Φßstφ hierarchie tvar∙, jako zde:
    // hierarchie tvar∙
    class shape {
       virtual void draw();
    };
    class circle : public shape {
       void draw();
    };
    class square : public shape {
      void draw();
    };
    //  Vytvo°enφ vektoru tvar∙
    circle c;
    square s;
    vector<shape*> v;
    v.push_back(&s);
    v.push_back(&c);
    // Volßnφ draw pro vÜechny
    for_each(v.begin(),v.end(), mem_fun(&shape::draw));
    Podobn∞ jako adaptΘry globßlnφch funkcφ i adaptΘry metod obsahujφ Üablonu t°φd a p°i°azenou Üablonu funkce. T°φda je aktußlnφ adaptΘr, zatφmco funkce zjednoduÜuje pou₧itφ t°φdy vytvo°enφm instance tΘto t°φdy. Nap°. v nßsledujφcφm p°φklad∞ vytvß°φme mem_fun_t sami, a pak ji p°edßme algoritmu for_each:
    mem_fun_t<shape> mf(&shape::draw);
    for_each(v.begin(),v.end(),mf);
    M∙₧eme takΘ vid∞t, ₧e Üablona funkce mem_fun zjednoduÜuje pou₧itφ adaptΘru mem_fun_t umo₧n∞nφm poΦφtaΦi vytvo°it typy po₧adovanΘ mem_fun_t. Knihovna poskytuje metody adaptΘr∙ bez parametr∙ a s jednφm parametrem. To m∙₧e zjednoduÜit Üφ°enφ metod s vφce parametry.
  29. Negßto°i a spojovaΦi jsou funkce adaptΘr∙, kterΘ jsou pou₧ity k budovßnφ nov²ch objekt∙ funkcφ mimo existujφcφ objekty funkcφ. V∞tÜinou jsou aplikovßny na funkce jako Φßst procesu budovßnφ seznamu parametr∙ p°ed vyvolßnφm jinΘ funkce nebo obecnΘho algoritmu.

  30. Negßtory not1 a not2 p°ebφrajφ unßrnφ a binßrnφ objekt funkce tvrzenφ a vytvß°ejφ nov² objekt funkce, kter² je dopl≥kem originßlu. Nap°. pou₧ijeme-li objekt funkce definovan² v p°edchozφm bod∞, pak objekt funkce
       not2(WidgetTester())
    poskytuje binßrnφ tvrzenφ, kterΘ p°ebφrß p°esn∞ stejnΘ parametry jako WidgetTester a mß znegovan² v²sledek. Negßto°i pracujφ pouze s objekty funkce definovan²mi jako podt°φdy t°φd unary_function a binary_function.
    SpojovaΦ p°ebφrß dvouparametrovou funkci a spojuje parametr urΦujφcφ funkci s parametrem obsahujφcφm hodnotu, tj. vytvß°φ jednoparametrovou funkci. Funkce musφ b²t podt°φdou t°φdy binary_function. SpojovaΦ bind1st spojuje prvnφ parametr zatφmco spojovaΦ bind2nd spojuje druh².
    Nap°. spojovaΦ bind2nd(greater<int>(), 5) vytvß°φ objekt funkce, kter² testuje zda hodnota je v∞tÜφ ne₧ 5. M∙₧eme ji pou₧φt k vytvo°enφ iterßtoru reprezentujφcφho prvnφ hodnotu v seznamu v∞tÜφ ne₧ 5:
    list<int>::iterator where = find_if(aList.begin(), aList.end(),
               bind2nd(greater<int>(), 5));
    Kombinacφ spojovaΦe a negßtoru m∙₧eme vytvo°it funkci, kterß mß hodnotu true, pokud parametr je d∞liteln² 3 a false v opaΦnΘm p°φpad∞. To m∙₧eme pou₧φt k odstran∞nφ vÜech nßsobk∙ 3 ze seznamu:
    list<int>::iterator where = remove_if (aList.begin(), aList.end(),
               not1(bind2nd(modulus<int>(), 3)));

  31. Standardnφ knihovna poskytuje 10 alternativnφch forem kontejner∙. V tΘto sekci struΦn∞ popφÜeme jejich charakteristiky. V nßsledujφcφch sekcφch pak jsou popsßny jednotlivΘ typy kontejner∙ podrobn∞ji. Charakteristiky kontejner∙ jsou uvedeny v nßsledujφcφ tabulce.

  32.  
    JmΘno
    Charakteristika
    vector nßhodn² p°φstup k prvk∙m, efektivnφ vklßdßnφ na konec
    list efektivnφ vklßdßnφ a odstra≥ovßnφ kdekoliv
    deque nßhodn² p°φstup, efektivnφ vklßdßnφ na zaΦßtek a konec
    set prvky udr₧ovßny v po°adφ, efektivnφ testovßnφ obsahu, vklßdßnφ a odstra≥ovßnφ
    multiset mno₧ina s opakovan²mi prvky
    map p°φstup k hodnotßm prost°ednictvφm klφΦ∙, efektivnφ vklßdßnφ a odstra≥ovßnφ
    multimap map  umo₧≥ujφcφ duplicitnφ klφΦe
    stack vklßdßnφ a odstra≥ovßnφ pouze na vrcholu
    queue vklßdßnφ na konec, odstra≥ovßnφ ze zaΦßtku
    priority queue efektivnφ p°φstup a odstran∞nφ nejv∞tÜφ hodnoty

    Kontejnery ve standardnφ knihovn∞ mohou udr₧ovat r∙znΘ typy prvk∙. Zahrnujφ zßkladnφ datovΘ typy (int, char apod.), ukazatele nebo u₧ivatelem definovanΘ typy. Kontejnery nemohou obsahovat odkazy. Obecn∞ sprßva pam∞ti je provßd∞na automaticky standardnφmi t°φdami kontejner∙ s malou spolupracφ programßtora.
    Hodnoty jsou umφs¥ovßny do kontejneru kopφrovacφm konstruktorem. Pro v∞tÜinu t°φd kontejner∙ musφ typ prvku dr₧en² kontejnerem takΘ definovat implicitnφ konstruktor. Obecn² algoritmus, kter² kopφruje do kontejneru (jako je copy) pou₧φvß operßtor p°i°azenφ.
    Kdy₧ je cel² kontejner duplikovßn (nap°. vyvolßnφm kopφrovacφho konstruktoru nebo jako v²sledek p°i°azenφ), pak ka₧dß hodnota je p°ekopφrovßna do novΘ struktury (v zßvislosti na struktu°e) operßtorem p°i°azenφ nebo kopφrovacφm konstruktorem. Pam∞¥ pro struktury pou₧itß intern∞ r∙zn²mi t°φdami kontejner∙ je alokovßna a uvol≥ovßna automaticky a efektivn∞.
    Pokud pro typ prvku je definovßn destruktor, pak tento destruktor je vyvolßvßn p°i odstra≥ovßnφ hodnot z kontejneru. P°i ruÜenφ celΘ kolekce, je destruktor vyvolßvßn, pro ka₧dou hodnotu dr₧enou v kontejneru.
    N∞kolik slov si °ekneme i o kontejnerech, kterΘ dr₧φ ukazatele. Nap°. kolekce ukazatel∙ je pouze zp∙sob ulo₧enφ hodnot, kterΘ m∙₧eme reprezentovat instancemi t°φdy nebo instancemi podt°φdy. V t∞chto p°φpadech je kontejner zodpov∞dn² pouze za udr₧ovßnφ samotn²ch ukazatel∙. Za sprßvu pam∞ti, na kterou ukazatele ukazujφ, zodpovφdß programßtor. To zahrnuje alokovßnφ (pomocφ operßtoru new) a na zßv∞r p°ed odstran∞nφm ukazatele z kontejneru, uvoln∞nφ prvku.
    Je n∞kolik klasick²ch kontejner∙, kterΘ nenajdeme ve standardnφ knihovn∞. Ve v∞tÜin∞ p°φpad∙ je d∙vod ten, ₧e kontejner, kter² mß b²t poskytnut, m∙₧e b²t snadno vytvo°en. Nemßme zde nap°. kontejner stromu. Datov² typ set je intern∞ implementovßn pomocφ binßrnφho vyhledßvacφho stromu. Pro mnoho problΘm∙ kterΘ vy₧adujφ pou₧itφ strom∙ je datov² typ set adekvßtnφ nßhradou. Datov² typ set je specißln∞ °azen a nenφ urΦen pro provßd∞nφ mno₧inov²ch operacφ na kolekci hodnot, kterΘ nemohou b²t °azeny (nap°. na mno₧in∞ komplexnφch Φφsel). V t∞chto p°φpadech jako nßhradu lze pou₧φt seznam, i kdy₧ zde budeme muset zapsat funkce pro specißlnφ mno₧inovΘ operace.
    Nejsou zde takΘ vφcerozm∞rnß pole, ale vektor m∙₧e obsahovat jinΘ vektory jako prvky a tak po₧adovanß struktura m∙₧e b²t snadno vytvo°ena.
    Knihovna neobsahuje takΘ grafy. Jedna reprezentace grafu m∙₧e b²t snadno vytvo°ena typem map, kter² dr₧φ dalÜφ map. Nejsou zde takΘ °φdkß pole. ╪eÜenφm tohoto problΘmu je pou₧itφ grafovΘ reprezentace. TakΘ nemßme heÜovacφ tabulky. M∙₧eme je snadno vytvo°it jako vector (nebo deque), kter² dr₧φ seznamy nebo mno₧iny jako svΘ prvky.


  33. T°φda kontejneru vector zobec≥uje koncepci pole jazyka C. Podobn∞ jako pole i vector je indexovanß datovß struktura, s hodnotami index∙ od 0 do poΦtu prvk∙ obsa₧en²ch ve struktu°e zmenÜenΘ o 1. TakΘ jako u pole, hodnoty prvk∙ mohou b²t p°i°azovßny a zφskßvßny pomocφ operßtoru indexace.

  34. Vektor se ale liÜφ od pole v nßsledujφcφch d∙le₧it²ch v∞cech: T°φdu kontejneru vector ve standardnφ knihovn∞ m∙₧eme porovnat s t°φdou kontejneru deque. Jako vektor i deque je indexovanß datovß struktura. Hlavnφ rozdφl je ten, ₧e deque poskytuje efektivnφ vklßdßnφ na zaΦßtek a konec kontejneru, zatφmco vektor poskytuje efektivnφ vklßdßnφ pouze na konec. V mnoha situacφch mohou b²t pou₧ity ob∞ struktury. P°i pou₧itφ vektoru obecn∞ dostaneme menÜφ spustiteln² soubor, zatφmco v zßvislosti na mno₧in∞ pou₧φvan²ch operacφ, pou₧itφ deque m∙₧e produkovat rychlejÜφ program.
    Kdy₧ pou₧φvßme vektor, pak do programu musφme vlo₧it hlaviΦkov² soubor vector:
    # include <vector>
  35. Nynφ se budeme zab²vat popisem metod datovΘho typy vektor. Proto₧e se jednß o Üablonu t°φdy, deklarace vektoru musφ zahrnovat urΦenφ typu prvk∙ kontejneru. M∙₧e to b²t primitivnφ typ (jako int nebo double), typ ukazatel nebo u₧ivatelem definovan² typ. V poslednφm p°φpad∞, u₧ivatelem definovan² typ musφ implementovat implicitnφ konstruktor (bude pou₧it k inicializaci nov∞ vytvo°en²ch prvk∙). Kopφrovacφ konstruktor (definovan² explicitn∞ nebo implicitn∞) musφ takΘ existovat pro typ prvku kontejneru. Podobn∞ jako pole, i vektor je Φasto deklarovßn s celoΦφseln²m parametrem, kter² urΦuje poΦet prvk∙ vektoru:

  36. vector<int> vec_one(10);
    Konstruktor pou₧it² v tΘto situaci k vytvo°enφ vektoru je deklarovßn jako explicitnφ, co₧ zabra≥uje, aby byl pou₧it jako konverznφ operßtor (obecn∞ je to vhodnΘ, nebo¥ jinak celΘ Φφslo m∙₧e b²t ne°φzen∞ p°evedeno v jist²ch situacφch na vektor).
    Konstruktor pou₧φvan² k vytvß°enφ vektor∙ m∙₧e mφt r∙znΘ tvary. Mimo velikosti, konstruktor m∙₧e p°ebφrat konstantnφ hodnotu, kterß bude pou₧ita k inicializaci vÜech prvk∙ pole. Pokud nenφ poskytnuta velikost, pak vektor zpoΦßtku neobsahuje ₧ßdn² prvek a je zv∞tÜovßn automaticky p°i p°idßvßnφ prvku. Kopφrovacφ konstruktor vytvß°φ klon vektoru z jinΘho vektoru.
    vector<int> vec_two(5, 3);      // kopφrovacφ konstruktor
    vector<int> vec_three;
    vector<int> vec_four(vec_two);  // inicializace p°i°azenφm
    Vektor m∙₧e b²t takΘ inicializovßn pomocφ prvk∙ z jinΘ kolekce zadßnφm poΦßteΦnφho a koncovΘho iterßtoru. Parametry mohou b²t libovoln²m tvarem iterßtoru, tedy kolekce m∙₧e b²t inicializovßna hodnotami z libovolnΘ t°φdy kontejneru ve standardnφ knihovn∞ kterß podporuje iterßtory.
    vector <int> vec_five (aList.begin(), aList.end());
    Vektor m∙₧e p°i°adit hodnoty jinΘmu vektoru (je p°i°azena kopie vektoru):
    vec_three = vec_five;
    Metoda assign se podobß p°i°azenφ, ale je mnohostrann∞jÜφ a v n∞kter²ch p°φpadech vy₧aduje vφce parametr∙. Podobn∞ jako u p°i°azenφ, existujφcφ hodnoty v kontejneru jsou zruÜeny a nahrazeny hodnotami urΦen²mi parametry. Jsou dva tvary assign. Prvnφ p°ebφrß dva parametry (iterßtory), kterΘ specifikujφ sekvenci v existujφcφm kontejneru. Hodnoty z tΘto sekvence jsou p°i°azeny. Druhß verze assign p°ebφrß poΦet a volitelnou hodnotu typu prvk∙ kontejneru. Po ukonΦenφ volßnφ, bude kontejner obsahovat pouze poΦet prvk∙ urΦen²ch prvnφm parametrem, kterΘ jsou rovny implicitnφ hodnot∞ pro typ prvku kontejneru nebo specifikovanΘ poΦßteΦnφ hodnot∞ (p°φpadn² druh² parametr).
    vec_six.assign(list_ten.begin(), list_ten.end());
    vec_four.assign(3, 7);      // t°i kopie hodnoty 7
    vec_five.assign(12);        // dvanßct kopiφ hodnoty 0
    Pokud je definovßn destruktor pro typ prvku kontejneru, pak destruktor bude volßn pro ka₧dou hodnotu odstra≥ovanou z kolekce.
    Dva vektory takΘ mohou zam∞nit svΘ celΘ obsahy pomocφ operace swap. Kontejner parametru p°evezme hodnoty kontejneru objektu a naopak.
    vec_three.swap(vec_four);
    T°φda vector obsahuje n∞kolik definicφ typ∙. Jsou Φasto pou₧φvßny v deklaraΦnφch p°φkazech. Nap°. iterßtor pro vektor cel²ch Φφsel m∙₧e b²t deklarovßn takto:
    vector<int>::iterator location;
    Mimo iterator jsou definovßny nßsledujφcφ typy:
     
    value_type Typ prvku vektoru.
    const_iterator Iterßtor, kter² neumo₧≥uje modifikaci p°ipojenΘ sekvence.
    reverse_iterator Iterßtor, kter² se p°esouvß sm∞rem dozadu.
    const_reverse_iterator Kombinace konstantnφho a reverznφho iterßtoru.
    reference Odkaz na p°ipojen² prvek.
    const_reference Odkaz na p°ipojen² prvek, kter² neumo₧≥uje modifikaci prvku.
    size_type Typ pou₧it² k odkazovßnφ na velikost kontejneru.
    difference_type Typ pou₧it² k ulo₧enφ vzdßlenosti mezi iterßtory.
    allocator_type  Typ alokßtoru pou₧itΘho pro sprßvu pam∞ti pro vektor.

    Stejn∞ jako u pole i u vektoru se pro p°φstup a modifikaci jednotliv²ch prvk∙ vektoru pou₧φvß operßtor indexace. V souΦasnΘ verzi nenφ mo₧no ov∞°it p°φpustnost hodnoty indexu (m∙₧e se v nßsledujφcφch verzφch zm∞nit). Indexace konstantnφho vektoru dßvß konstantnφ odkaz. Pokus o indexaci vektoru mimo rozsah p°φpustn²ch hodnot generuje nep°edvφdateln² a chybn² v²sledek:
    cout << vec_five[1] << endl;
    vec_five[1] = 17;
    Metoda at m∙₧e b²t pou₧ita mφsto operßtoru indexace. P°ebφrß stejnΘ parametry jako operßtor indexace a vracφ p°esn∞ stejn² v²sledek.
    Metoda front vracφ prvnφ prvek ve vektoru, zatφmco metoda back poskytuje poslednφ prvek. Ob∞ takΘ vracejφ konstantnφ odkazy, kdy₧ jsou aplikovßny na konstantnφ vektory.
    cout << vec_five.front() << " ... " << vec_five.back() << endl;
    Obecn∞ jsou t°i r∙znΘ velikosti p°i°azenΘ k libovolnΘmu vektoru. Prvnφm je poΦet prvk∙ souΦasn∞ dr₧en²ch vektorem. Druh²m je maximßlnφ velikost, na kterou vektor se m∙₧e rozÜφ°it bez po₧adavk∙ na alokovßnφ novΘho mφsta. T°etφm je hornφ limit velikosti libovolnΘho vektoru. Tyto t°i hodnoty zφskßme metodami size, capacity a max_size.
    cout << "velikost: " << vec_five.size() << endl;
    cout << "kapacita: " << vec_five.capacity() << endl;
    cout << "max_velikost: " << vec_five.max_size() << endl;
    Maximßlnφ velikost je obvykle omezena pouze dostupnou pam∞tφ nebo nejv∞tÜφ hodnotou, kterß m∙₧e b²t ulo₧ena v datovΘm typu size_type. Charakterizovat souΦasnou velikost a kapacitu je slo₧it∞jÜφ. Jak jsme se ji₧ dozv∞d∞li, prvky mohou b²t p°idßvßny do a odstra≥ovßny z vektoru r∙zn²mi zp∙soby. Kdy₧ prvky jsou z vektoru odstran∞ny, pak pam∞¥ pro vektor obvykle nenφ realokovßna a tedy velikost se zmenÜφ, ale kapacita z∙stßvß stejnß. ╪ada vklßdßnφ nevy₧aduje realokaci novΘ pam∞ti, pokud p∙vodnφ kapacita nenφ p°ekroΦena.
    Vklßdßnφ, kterΘ zp∙sobφ, ₧e velikost p°ekroΦφ kapacitu obecn∞ zp∙sobφ alokovßnφ novΘho bloku pam∞ti pro ulo₧enφ prvk∙ vektoru. Hodnoty jsou pak kopφrovßny do tΘto novΘ pam∞ti pomocφ operßtoru p°i°azenφ a starß pam∞¥ je zruÜena. Proto₧e to m∙₧e b²t potencißln∞ nßkladnß operace, datov² typ vector umo₧≥uje programßtoru specifikovat hodnotu kapacity vektoru. Metoda reserve je direktiva pro vektor, indikujφcφ, ₧e vektor mß b²t zv∞tÜen alespo≥ na danou velikost. Pokud parametr reserve je v∞tÜφ ne₧ souΦasnß kapacita, pak nastane realokace a hodnota parametru urΦuje novou kapacitu. Pokud kapacita ji₧ p°ekraΦuje hodnotu parametru, pak k ₧ßdnΘ realokaci nedojde. Vyvolßnφ reserve nem∞nφ velikost vektoru ani hodnoty samotn²ch prvk∙.
    vec_five.reserve(20);
    Realokace znehodnotφ vÜechny odkazy, ukazatele a iterßtory odkazujφcφ se na prvky dr₧enΘ vektorem.
    Metoda empty vracφ true, pokud souΦasnß velikost vektoru je nula (bez ohledu na kapacitu vektoru). Pou₧itφ tΘto metody je obecn∞ efektivn∞jÜφ ne₧ porovnßvßnφ vrßcenΘ velikosti s nulou.
    cout << "je prßzdn² " << vec_five.empty() << endl;
    Metoda resize m∞nφ velikost vektoru na hodnotu specifikovanou parametrem. Hodnoty mohou b²t p°idßny na nebo zruÜeny z konce kolekce podle pot°eby. Voliteln² druh² parametr m∙₧e b²t pou₧it pro poskytnutφ poΦßteΦnφ hodnoty nov²ch prvk∙ p°idan²ch do kolekce. Pokud je definovßn destruktor pro typ prvku, pak je vyvolßvßn pro vÜechny hodnoty odstra≥ovanΘ z kolekce.
    // velikost bude 12 a v p°φpad∞ pot°eby budou p°idßny hodnoty 17
    vec_five.resize (12, 17);
    Jak ji₧ bylo uvedeno v²Üe, t°φda vector se liÜφ od b∞₧nΘho pole tφm, ₧e vektor m∙₧e v jist²ch situacφch zv∞tÜovat nebo zmenÜovat svou velikost. Kdy₧ vklßdßnφ zp∙sobφ, ₧e poΦet prvk∙ dr₧en²ch ve vektoru p°ekroΦφ kapacitu vektoru, pak je alokovßn nov² blok a prvky jsou p°ekopφrovßny na novΘ mφsto.
    Nov² prvek m∙₧e b²t p°idßn na konec vektoru pomocφ metody push_back. Pokud v souΦasnΘ alokaci je mφsto, pak tato operace je velmi efektivnφ.
    vec_five.push_back(21);   // p°idßnφ prvku 21 na konec vektoru
    Odpovφdajφcφ odstra≥ovacφ operace je pop_back, kterß zmenÜuje velikost vektoru, ale nem∞nφ jeho kapacitu. Tato operace je op∞t znaΦn∞ efektivnφ.
    Obecn∞jÜφ vklßdacφ operace m∙₧e b²t provßd∞na metodou insert. Mφsto vlo₧enφ je popsßno iterßtorem, vlo₧enφ prob∞hne bezprost°edn∞ p°ed urΦenΘ mφsto. Pevn² poΦet stejn²ch prvk∙ m∙₧e b²t vlo₧en jednφm volßnφm. Je efektivn∞jÜφ vklßdßnφ bloku prvk∙ jednφm volßnφm ne₧ provßd∞nφ °ady jednotliv²ch vklßdßnφ, proto₧e jedno volßnφ provede nejv²Üe jednu alokaci.
    // nalezenφ 7
    vector<int>::iterator where = find(vec_five.begin(), vec_five.end(), 7);
    vec_five.insert(where, 12);    // vlo₧enφ 12 p°ed 7
    vec_five.insert(where, 6, 14); // vlo₧enφ Üest kopiφ 14
    Obecn∞jÜφ tvar metody insert p°ebφrß pozici a dvojici iterßtor∙, kterΘ urΦujφ sekvenci z jinΘho kontejneru. Rozsah hodnot popsan²ch sekvencφ je vlo₧en do vektoru. Pou₧itφ tΘto funkce je v²hodn∞jÜφ ne₧ provedenφ °ady jednotliv²ch vklßdßnφ.
    vec_five.insert (where, vec_three.begin(), vec_three.end());
    Mimo metody pop_back, kterß odstra≥uje prvek z konce vektoru, existuje takΘ metoda odstra≥ujφcφ prvky z prost°edku vektoru, kde pozice odstra≥ovanΘho prvku je urΦena iterßtorem. Jednß se o metodu erase. Metoda mß dva tvary: prvnφ p°ebφrß jeden iterßtor a odstra≥uje jednu hodnotu, zatφmco druh² p°ebφrß dvojici iterßtor∙ a odstra≥uje hodnoty v danΘm rozsahu. Velikost vektoru je zmenÜena, ale kapacita se nem∞nφ.
    vec_five.erase(where);
    // zruÜenφ od hodnoty 12 do konce
    where = find(vec_five.begin(), vec_five.end(), 12);
    vec_five.erase(where, vec_five.end());
    Metody begin  a end vytvß°ejφ iterßtory nßhodnΘho p°φstupu pro kontejner. Pamatujte, ₧e iterßtory z°φzenΘ t∞mito operacemi mohou b²t znehodnoceny vlo₧enφm nebo odstran∞nφm prvk∙. Metody rbegin a rend vracejφ podobnΘ iterßtory, kterΘ ale umo₧≥ujφ p°istupovat k prvk∙m v opaΦnΘm po°adφ. Konstantnφ iterßtory jsou vrßceny, pokud kontejner je p∙vodn∞ deklarovßn jako konstantnφ nebo pokud cφl p°i°azenφ nebo parametr je konstantnφ.
    Vektor neposkytuje ₧ßdnou metodu, kterß m∙₧e b²t p°φmo pou₧ita k urΦenφ zda specifickß hodnota je obsa₧ena v kolekci. Pro tento ·Φel m∙₧e b²t ale pou₧it obecn² algoritmus find nebo count. Nßsledujφcφ p°φkaz nap°. testuje zda celoΦφseln² vektor obsahuje hodnotu 17:
    int num = 0;
    count (vec_five.begin(), vec_five.end(), 17, num);
    if (num) cout << "obsahuje 17" << endl;
    else cout << "neobsahuje 17" << endl;
    Vektor automaticky neudr₧uje svΘ hodnoty v rostoucφ sekvenci. M∙₧e b²t ale uveden do po°adφ pomocφ obecnΘho algoritmu sort. JednoduÜÜφ forma °azenφ pou₧φvß pro svΘ porovnßvßnφ operßtor menÜφ ne₧ pro typ prvku. Alternativnφ verze obecnΘho algoritmu po₧aduje od programßtora explicitnφ specifikaci porovnßvacφho operßtoru. Ten pak m∙₧e b²t pou₧it nap°. k umφst∞nφ prvk∙ v sestupnΘm namφsto vzestupnΘho po°adφ:
    sort (aVec.begin(), aVec.end());  // vzestupnΘ °azenφ
    sort (aVec.begin(), aVec.end(), greater<int>() ); // specifikace operßtoru
    sort (aVec.rbegin(), aVec.rend()); // alternativnφ zp∙sob sestupnΘho °azenφ
    Mnoho z obecn²ch algoritm∙ m∙₧e b²t pou₧ito s vektory. Jsou uvedeny v nßsledujφcφ tabulce. Nap°. maximßlnφ hodnota vektoru m∙₧e b²t urΦena takto:
    vector<int>::iterator where = max_element(vec_five.begin(), vec_five.end());
    cout << "maximum je " << *where << endl;
     
    ╚innost JmΘno
    Plnφ vektor dan²mi poΦßteΦnφmi hodnotami fill
    Kopφruje jednu sekvenci do druhΘ copy
    Kopφruje hodnoty z generßtoru do vektoru generate
    Hledß prvek spl≥ujφcφ podmφnku find
    Hledß p°φpadnΘ duplicitnφ prvky adjacent_find
    Hledß podsekvenci ve vektoru search
    Lokalizuje maximßlnφ nebo minimßlnφ prvek max_element, min_element
    Obracφ po°adφ prvk∙ reverse
    Nahrazuje prvky nov²mi hodnotami replace
    Rotuje prvky okolo st°edu rotate
    Rozd∞luje prvky do skupin partition
    Generovßnφ permutacφ next_permutation
    Spojovßnφ vektor∙ inplace_merge
    NßhodnΘ zapln∞nφ prvk∙ vektoru random_shuffle
    PoΦet prvk∙ spl≥ujφcφch podmφnku count
    Redukce vektoru na jednu hodnotu accumulate
    Vnit°nφ produkt vektor∙  inner_product
    Test dvou vektor∙ na rovnost pßr∙ equal
    LexikografickΘ porovnßvßnφ lexicographical_compare
    Aplikovßnφ transformace na vektor transform
    ╚ßsteΦnΘ souΦty hodnot partial_sum
    Rozdφly sousednφch hodnot adjacent_difference
    Provedenφ funkce pro ka₧d² prvek for_each

  37. Vektory bit∙ (hodnot 0/1) jsou zpracovßvßny standardnφ knihovnou specißlnφm zp∙sobem, kdy hodnoty jsou efektivn∞ pakovßny (n∞kolik prvk∙ do slova). Operace pro logick² vektor vector<bool> jsou nadmno₧inou operacφ normßlnφho vektoru. Novß p°idanß metoda pro logick² vektor je flip. Jejφm vyvolßnφm invertujeme vÜechny bity vektoru. LogickΘ vektory takΘ vracejφ jako odkaz internφ hodnotu, kterou takΘ podporuje metoda flip.

  38. vector<bool> bvec(27);
    bvec.flip();               // inverze vÜech prvk∙
    bvec[17].flip();           // inverze bitu 17
    Logick² vektor takΘ podporuje metodu swap, kterß umo₧≥uje vym∞niti hodnoty urΦenΘ dvojicφ odkaz∙:
    bvec.swap(bvec [17], bvec [16]);
  39. P°φklad programu, kter² ukazuje pou₧itφ vektor∙ je klasick² algoritmus nazvan² Eratosovo sφto, pou₧φvan² k urΦenφ prvoΦφsel. Seznam vÜech Φφsel pat°φcφch do n∞jakΘho intervalu je reprezentovßn celoΦφseln²m vektorem. Zßkladnφ myÜlenkou je vy°azenφ (nastavenφm na 0) t∞ch hodnot, kterΘ nemohou b²t prvoΦφsly a tedy vÜechny zb²vajφcφ hodnoty jsou prvoΦφsly. Provedeme to tak, ₧e v cyklu testujeme ka₧dou hodnotu a vy°azujeme ty, kterΘ jsou d∞litelnΘ. Kdy₧ skonΦφ vn∞jÜφ cyklus, pak vÜechny hodnoty prvoΦφsel jsou nalezeny. Program vypadß takto:

  40. void main() {
       const int sievesize = 100;
       vector<int> sieve(sievesize, 1);
       for (int i = 2; i * i < sievesize; i++)
          if (sieve[i])
             for (int j = i + i; j < sievesize; j += i)
                sieve[j] = 0;
       for (int j = 2; j < sievesize; j++)
          if (sieve[j])
             cout << j << " ";
       cout << endl;
    }

  41. Datovß struktura vektor je kontejner relativn∞ pevnΘ velikosti. I kdy₧ standardnφ knihovna poskytuje slu₧by pro dynamickou zm∞nu velikosti vektoru, tyto operace jsou nßkladnΘ a je vhodnΘ je rad∞ji nepou₧φvat. V mnoha p°φpadech m∙₧e b²t znaΦn∞ obtφ₧nΘ urΦit p°edem velikost kolekce nebo velikost se v pr∙b∞hu provßd∞nφ m∙₧e znaΦn∞ m∞nit. V t∞chto p°φpadech je vhodnΘ pou₧φvat jinou datovou strukturu. Nynφ se seznßmφme s alternativnφ datovou strukturou, kterß m∙₧e b²t pou₧ita v t∞chto situacφch, a to s datov²m typem list.

  42. Seznam odpovφdß intuitivnφ myÜlence dr₧enφ prvk∙ v lineßrnφ sekvenci. NovΘ hodnoty mohou b²t p°idßvßny na nebo odstra≥ovßny ze zaΦßtku nebo konce seznamu. Pomocφ iterßtoru lze urΦit pozici a prvky mohou b²t p°idßvßny do nebo odstra≥ovßny z prost°edku seznamu. Ve vÜech p°φpadech vklßdacφ nebo odstra≥ovacφ operace jsou efektivnφ a doba jejich provedenφ nenφ zßvislß na poΦtu prvk∙ kolekce. Seznam je lineßrnφ struktura. Obsah seznamu nem∙₧e b²t zp°φstup≥ovßn indexacφ a obecn∞ prvky mohou b²t zp°φstup≥ovßny pouze lineßrnφm prochßzenφm vÜech hodnot.
    Kdy₧ pou₧φvßme seznam, pak musφme do programu vlo₧it hlaviΦkov² soubor list:
    # include <list>
  43. Jsou r∙znΘ zp∙soby deklarace seznamu. V nejjednoduÜÜφm tvaru seznam je deklarovßn uvedenφm typu prvku seznamu. M∙₧e to b²t primitivnφ datov² typ, typ ukazatel nebo u₧ivatelem definovan² typ. V poslednφm p°φpad∞ typ definovan² u₧ivatelem musφ implementovat implicitnφ konstruktor a tento konstruktor je v n∞kter²ch p°φpadech pou₧it k inicializaci nov∞ vytvo°en²ch prvk∙. Kolekce deklarovanΘ tφmto zp∙sobem p∙vodn∞ neobsahujφ ₧ßdnΘ prvky.

  44. list <int> list_one;
    list <Widget *> list_two;
    list <Widget> list_three;
    Alternativnφ tvar deklarace vytvß°φ kolekci, kterß p∙vodn∞ obsahuje n∞jak² poΦet stejn²ch prvk∙. Konstruktor pro tento tvar je deklarovßn jako explicitnφ, co₧ znamenß, ₧e nem∙₧e b²t pou₧it jako konverznφ operßtor. Konstruktor v tomto p°φpad∞ p°ebφrß dva parametry, velikost a poΦßteΦnφ hodnotu. Druh² parametr je voliteln². Pokud je uveden pouze poΦet prvk∙, pak hodnoty jsou inicializovßny implicitnφm konstruktorem, jinak jsou prvky inicializovßny hodnotou druhΘho parametru:
    list <int> list_four (5);  // p∞t prvk∙ inicializovan²ch nulou
    list <double> list_five (4, 3.14);   // 4 hodnoty inicializovanΘ 3.14
    list <Widget> wlist_six (4);  // implicitnφ konstruktor, 4 prvky
    list <Widget> list_six (3, Widget(7));  // 3 kopie Widget(7)
    Seznamy mohou b²t takΘ inicializovßny prvky z jinΘ kolekce, pomocφ dvojice poΦßteΦnφho a koncovΘho iterßtoru. Parametry mohou b²t libovoln²m tvarem iterßtoru a tedy kolekce m∙₧e b²t inicializovßna hodnotami z libovolnΘ t°φdy kontejneru ze standardnφ knihovny, kterß podporuje iterßtory. Jako alternativnφ technika m∙₧e b²t pou₧it obecn² algoritmus copy. Kdy₧ je seznam inicializovßn pomocφ copy, pak musφ b²t vytvo°en vklßdacφ iterßtor pro p°evod v²stupnφch operacφ provßd∞n²ch operacφ copy na vklßdßnφ. inserter vy₧aduje dva parametry; seznam do kterΘho budou hodnoty vklßdßny a iterßtor indikujφcφ mφsto kam prvky budou vlo₧eny. Vklßdacφ operßtory mohou b²t takΘ pou₧ity pro kopφrovßnφ prvk∙ na urΦenΘ mφsto v existujφcφm seznamu.
    list <double> list_seven (aVector.begin(), aVector.end());
    // ekvivalent p°edchozφho
    list <double> list_eight;
    copy (aVector.begin(), aVector.end(),
    inserter(list_eight, list_eight.begin()));
    Vklßdacφ iterßtory mohou b²t pou₧ity k inicializaci seznamu sekvencφ hodnot vytvo°en²ch generßtorem. To ukazuje:
    list <int> list_nine;
    // inicializace seznamu 1 2 3 ... 7
    generate_n (inserter(list_nine, list_nine.begin()), 7, iotaGen(1));
    Kopφrovacφ konstruktor m∙₧e b²t pou₧it k inicializaci seznamu hodnotami zφskan²mi z jinΘho seznamu. P°i°azovacφ operßtor provßdφ stejnΘ akce. V obou p°φpadech je pou₧it pro kopφrovßnφ ka₧dΘ novΘ hodnoty p°i°azovacφ operßtor pro typ prvku.
    list <int> list_ten (list_nine);          // kopφrovacφ konstruktor
    list <Widget> list_eleven;
    list_eleven = list_six;        // hodnoty kopφrovßny p°i°azenφm
    Metoda assign se podobß operßtoru p°i°azenφ, ale mß vφce mo₧nostφ a v n∞kter²ch p°φpadech vy₧aduje vφce parametr∙. Jejφ pou₧φvßnφ je stejnΘ jako u struktury vektor.
    list_six.assign(list_ten.begin(), list_ten.end());
    list_four.assign(3, 7);          // t°i kopie hodnoty 7
    list_five.assign(12);            // 12 kopiφ hodnoty 0
    Dva seznamy mohou takΘ zam∞nit svΘ obsahy operacφ swap. Nap°.
    list_ten.swap(list_nine);
    T°φda list obsahuje n∞kolik definic typ∙. V∞tÜinou se pou₧φvajφ v p°φkazech deklaracφ. Nap°. iterßtor pro seznam cel²ch Φφsel m∙₧eme deklarovat takto:
    list<int>::iterator location;
    Mimo iterator jsou definovßny nßsledujφcφ typy:
     
    value_type Typ p°i°azen² k prvk∙m seznamu.
    const_iterator  Iterßtor, kter² neumo₧≥uje modifikovat p°ipojenou sekvenci.
    reverse_iterator Iterßtor, kter² se p°esouvß sm∞rem dozadu.
    const_reverse_iterator Kombinace konstantnφho a reverznφho iterßtoru
    reference Odkaz na p°ipojen² prvek.
    const_reference  Odkaz na p°ipojen² prvek neumo₧≥ujφcφ modifikaci prvku.
    size_type Typ pou₧it² k odkazovßnφ na velikost kontejneru.
    difference_type Typ pou₧φvan² popisu vzdßlenosti mezi iterßtory.
    allocator_type Typ alokßtoru pou₧it² pro veÜkerou sprßvu uklßdßnφ seznamem.

    Hodnoty lze vklßdat do seznamu r∙zn²mi zp∙soby. Prvky jsou Φasto p°idßvßny na zaΦßtek nebo konec seznamu. Tyto ·lohy jsou provßd∞ny operacemi push_front a push_back.
    list_seven.push_front(1.2);
    list_eleven.push_back (Widget(6));
    Ji₧ jsme si °ekli, ₧e m∙₧eme pou₧φt vklßdacφ iterßtor spoleΦn∞ s obecn²mi algoritmy copy nebo generate pro umφs¥ovßnφ hodnot do seznamu. Je takΘ metoda insert, kterß nevy₧aduje vytvß°enφ vklßdacφho iterßtoru. Hodnoty vrßcenΘ generaΦnφmi funkcemi iterßtor∙ begin a end urΦujφ zaΦßtek a konec seznamu. Vklßdßnφ pomocφ nich je ekvivalentnφ push_front nebo push_back. Pokud specifikujeme pouze iterßtor, pak je vlo₧en implicitnφ prvek.
    // vlo₧enφ implicitnφ hodnoty na zaΦßtek seznamu
    list_eleven.insert(list_eleven.begin());
    // vlo₧enφ widget(8) na konec seznamu
    list_eleven.insert(list_eleven.end(), Widget(8));
    Iterßtor m∙₧e urΦovat pozici i uprost°ed seznamu. Je n∞kolik mo₧nostφ jak vytvo°it tento iterßtor. Nap°. m∙₧eme pou₧φt v²sledek n∞jakΘ vyhledßvacφ operace, jako je pou₧itφ obecnΘho algoritmu find. NovΘ hodnoty jsou vklßdßny bezprost°edn∞ p°ed mφsto urΦenΘ iterßtorem. Operace insert vracφ iterßtor urΦujφcφ mφsto vlo₧enΘ hodnoty. V²slednß hodnota (iterßtor) m∙₧e b²t ignorovßna jak bude ukßzßno pozd∞ji.
    // nalezenφ prvnφho v²skytu hodnoty 5 v seznamu
    list<int>::iterator location = find(list_nine.begin(), list_nine.end(), 5);
    // a vlo₧enφ hodnoty 11 bezprost°edn∞ p°ed nφ
    location = list_nine.insert(location, 11);
    Je takΘ mo₧no vklßdat pevn² poΦet kopiφ hodnoty parametru. Hodnota vrßcenß insert nenφ pou₧ita.
    line_nine.insert (location, 5, 12);       // vlo₧enφ 5 hodnot 12
    Do seznamu m∙₧e b²t takΘ vlo₧ena celß sekvence urΦenß pßrem iterßtor∙. Vrßcenß hodnota insert op∞t nenφ pou₧ita.
    // vlo₧enφ celΘho obsahu jednoho seznamu do jinΘho seznamu
    list_nine.insert (location, list_ten.begin(), list_ten.end());
    Jsou r∙znΘ zp∙soby splΘtßnφ jednoho seznamu s jin²m. SplΘtßnφ se liÜφ od vklßdßnφ v tom, ₧e prvky jsou souΦasn∞ p°idßvßny k seznamu p°φjemce a odstra≥ovßny ze seznamu parametru. Z tohoto d∙vodu splΘtßnφ je provßd∞no velmi efektivn∞. Metoda splice pou₧φvß iterßtor k indikaci mφsta v p°ijφmajφcφm seznamu, kam hodnoty budou vlo₧eny. Parametrem m∙₧e b²t cel² seznam, jeden prvek seznamu nebo podsekvence seznamu.
    list_nine.splice (location, list_ten, list_ten.end());
    list_nine.splice (location,  list_ten);
    list_ten.splice (list_ten.begin(), list_nine, list_nine.begin(), location);
    Dva se°azenΘ seznamy mohou b²t spojeny do jednoho operacφ merge. Hodnoty ze seznamu parametru jsou spojeny do se°azenΘho seznamu a parametrov² seznam je vyprßzdn∞n. Obecn² algoritmus stejnΘho jmΘna podporuje dva tvary. Jeden z nich nenφ podporovßn vÜemi p°ekladaΦi.
    // spojenφ s explicitnφ porovnßvacφ funkcφ
    list_eleven.merge(list_six, widgetCompare);
    // podobß se p°edchozφmu
    list<Widget> list_twelve;
    merge(list_eleven.begin(),list_eleven.end(),list_six.begin(),list_six.end(),
       inserter(list_twelve, list_twelve.begin()), widgetCompare);
    list_eleven.swap(list_twelve);
    Stejn∞ jako je n∞kolik r∙zn²ch zp∙sob∙ vklßdßnφ prvk∙ do seznamu, je takΘ n∞kolik r∙zn²ch zp∙sob∙ odstra≥ovßnφ prvk∙ ze seznamu. NejΦast∞ji pou₧φvanΘ operace k odstra≥ovßnφ hodnot jsou pop_front nebo pop_back, kterΘ ruÜφ jeden prvek ze zaΦßtku nebo konce seznamu. Tyto metody jednoduÜe odstranφ dan² prvek a jinak neposkytujφ ₧ßdn² u₧iteΦn² v²sledek. K prohlΘdnutφ prvk∙ p°ed zruÜenφm pou₧ijeme metody front nebo back.
    Operace erase m∙₧e b²t pou₧ita k odstran∞nφ hodnoty urΦenΘ iterßtorem. Pro seznam, iterßtor parametru a vÜechny ostatnφ iterßtory ukazujφcφ na stejnΘ mφsto, budou po odstran∞nφ prvku nep°φpustnΘ, ale ostatnφ iterßtory z∙stßvajφ i nadßle v platnosti. erase m∙₧eme takΘ pou₧φt k odstran∞nφ celΘ podsekvence urΦenΘ pßrem iterßtor∙.
    list_nine.erase (location);
    // zruÜenφ hodnot mezi prvnφm v²skytem 5 a nßsledujφcφ v²skytem 7
    list<int>::iterator location = find(list_nine.begin(), list_nine.end(), 5);
    list<int>::iterator location2 = find(location, list_nine.end(), 7);
    list_nine.erase (location, location2);
    Metoda remove odstra≥uje vÜechny v²skyty danΘ hodnoty ze seznamu. remove_if odstra≥uje vÜechny prvky spl≥ujφcφ danou podmφnku. Alternativou k jejich pou₧itφ jsou obecnΘ algoritmy stejnΘho jmΘna. Tyto obecnΘ algoritmy nezmenÜujφ velikost seznamu, pouze p°esouvajφ zb²vajφcφ prvky na zaΦßtek seznamu a vracejφ iterßtor urΦujφcφ prvnφ nep°esunut² prvek. Tato hodnota m∙₧e b²t pou₧ita metodou erase k odstran∞nφ zb²vajφcφch hodnot.
    list_nine.remove(4);                         // odstra≥uje vÜechny 4
    list_nine.remove_if(divisibleByThree);       // odstra≥uje vÜe d∞litelnΘ 3
    // ekvivalent p°edchozφho
    list<int>::iterator location3=remove_if(list_nine.begin(),list_nine.end(),
                  divisibleByThree);
    list_nine.erase(location3, list_nine.end());
    Operace unique ruÜφ vÜe mimo prvnφch prvk∙ z ka₧dΘ ekvivalentnφ skupiny prvk∙ v seznamu. Seznam nemusφ b²t se°azen. Alternativnφ verze p°ebφrß binßrnφ funkci, porovnßvß sousednφ prvky pomocφ tΘto funkce a odstra≥uje druhΘ hodnoty v t∞ch situacφch, kdy funkce vracφ hodnotu true. V nßsledujφcφm p°φklad∞ binßrnφ funkce je operßtor v∞tÜφ ne₧, kter² odstranφ vÜechny prvky menÜφ ne₧ p°edchozφ prvek.
    list_nine.unique();
    // explicitn∞ danß porovnßvacφ funkce
    list_nine.unique(greater<int>());
    // stejnΘ jako p°edchozφ
    location3 = unique(list_nine.begin(), list_nine.end(), greater<int>());
    list_nine.erase(location3, list_nine.end());
    Metoda size vracφ poΦet prvk∙ dr₧en²ch v kontejneru. Funkce empty vracφ true pokud kontejner je prßzdn² a je efektivn∞jÜφ ne₧ porovnßvßnφ zφskanΘ velikosti s nulou.
    cout << "PoΦet prvk∙: " << list_nine.size () << endl;
    if ( list_nine.empty () ) cout << "seznam je prßzdn² " << endl;
    else cout << "seznam nenφ prßzdn² " << endl;
    Metoda resize m∞nφ velikost seznamu na hodnotu specifikovanou parametrem. Z konce seznamu jsou odebrßny nebo p°idßny hodnoty podle pot°eby. Voliteln² druh² parametr m∙₧e b²t pou₧it jako poΦßteΦnφ hodnota pro p°idßvanΘ prvky.
    // zφskß velikost 12, p°idßvanΘ prvky jsou 17 (v p°φpad∞ pot°eby)
    list_nine.resize (12, 17);
    Metody front a back vracejφ, ale neodstra≥ujφ prvnφ a poslednφ prvek kontejneru. Pro seznam, p°φstup k ostatnφm prvk∙m je mo₧n² pouze odstra≥ovßnφm prvk∙ (dokud po₧adovan² prvek se nestane prvnφm nebo poslednφm) nebo pomocφ pou₧itφ iterßtor∙.
    Jsou r∙znΘ typy iterßtor∙, kterΘ mohou b²t vytvo°eny pro seznamy. Funkce begin a end vytvß°ejφ iterßtory kterΘ prochßzejφ seznamy dop°edu. Pro seznamy to jsou obousm∞rnΘ iterßtory. Alternativnφ funkce rbegin a rend vytvß°ejφ reverznφ iterßtory.
    Seznamy neposkytujφ p°φmo ₧ßdnou metodu, kterß m∙₧e b²t pou₧ita k urΦenφ, zda specifikovanß hodnota je obsa₧ena v kolekci. Pro tento ·Φel ale m∙₧eme pou₧φt obecnΘ algoritmy find nebo count. Nßsledujφcφ p°φkazy nap°. testujφ zda seznam cel²ch Φφsel obsahuje prvek 17.
    int num = 0;
    count(list_five.begin(), list_five.end(), 17, num);
    if (num > 0) cout << "obsahuje 17" << endl;
    else cout << "neobsahuje 17" << endl;
    // nebo
    if (find(list_five.begin(), list_five.end(), 17) != list_five.end())
       cout << "obsahuje 17" << endl;
    else cout << "neobsahuje 17" << endl;
    Metoda sort umφs¥uje prvky do vzestupnΘho po°adφ. Pokud je po₧adovßn jin² operßtor ne₧ <, pak musφ b²t p°edßn jako parametr.
    list_ten.sort ( );                      // se°azenφ prvk∙
    list_twelve.sort (widgetCompare);       // °azenφ s porovnßvacφ funkcφ
    Na seznamy m∙₧eme aplikovat °adu vyhledßvacφch funkcφ. Jednß se o find, find_if, mismatch, max_element, min_element, search apod. Ve vÜech p°φpadech v²sledkem je iterßtor, kter² m∙₧e b²t dereferencovßn k zφskßnφ urΦenΘho prvku nebo pou₧it jako parametr v nßsledujφcφ operaci.
    Na seznam mohou b²t takΘ aplikovßny operace, kterΘ m∞nφ jeho pozice. N∞kterΘ z nich jsou poskytnutΘ jako metody. Nap°. metoda reverse m∞nφ po°adφ prvk∙ v seznamu.
    list_ten.reverse();
    Obecn² algoritmus transform m∙₧e b²t pou₧it k modifikaci ka₧dΘ hodnoty v kontejneru, kde jako vstup a v²stup se pou₧φvß stejn² kontejner. Nßsleduje nap°. zv∞tÜenφ ka₧dΘho prvku v kontejneru o 1. K vytvo°enφ nutnΘ unßrnφ funkce, prvnφ parametr binßrnφ celoΦφselnΘ funkce je sestaven v jednu hodnotu. Verze transform, kterß manipuluje na dvou paralelnφch sekvencφch m∙₧e b²t pou₧ita podobn²m zp∙sobem.
    transform(list_ten.begin(), list_ten.end(), list_ten.begin(), bind1st(plus<int>(), 1));
    Podobn∞ funkce replace a replace_if mohou b²t pou₧ity k nahrazovßnφ prvk∙ v seznamu specifikovanou hodnotou. Se seznamy m∙₧eme takΘ provßd∞t rotace a rozd∞lovßnφ.
    // nalezenφ hodnoty 5 a rotace okolo nφ
    location = find(list_ten.begin(), list_ten.end(), 5);
    rotate(list_ten.begin(), location, list_ten.end());
    // Φßst pou₧φvß hodnoty v∞tÜφ ne₧ 7
    partition(list_ten.begin(), list_ten.end(), bind2nd(greater<int>(), 7));
    Funkce next_permutation a prev_permutation mohou b²t pou₧ity ke generovßnφ nßsledujφcφ (nebo p°edchozφ) permutace kolekce hodnot.
    next_permutation (list_ten.begin(), list_ten.end());
    Algoritmus for_each aplikuje funkci na ka₧d² prvek kolekce. Algoritmus accumulate redukuje kolekci na skalßrnφ hodnotu. M∙₧e to b²t nap°. pou₧ito na v²poΦet souΦtu seznamu.
    cout << "SouΦet seznamu je: " <<
            accumulate(list_ten.begin(), list_ten.end(), 0) << endl;
    Dva seznamy mohou b²t porovnßvßny jeden s druh²m. Jsou si rovny, pokud majφ stejnou velikost a vÜechny odpovφdajφcφ prvky si jsou rovny. Seznam je menÜφ ne₧ jin² seznam, pokud je lexikograficky menÜφ.

  45. Pro ilustraci pou₧itφ n∞kter²ch operacφ se seznamem pou₧ijeme p°φklad jednoduchΘho systΘmu sprßvy zßsob. P°edpoklßdejme podnik nazvan² WorldWideWidgetWorks, vy₧adujφcφ programov² systΘm pro sprßvu sv²ch zßsob za°φzenφ (widget). Za°φzenφ jsou rozliÜovßny identifikaΦnφmi Φφsly:

  46. class  Widget {
    public:
       Widget(int a = 0) : id(a) { }
       void operator = (const Widget& rhs) { id = rhs.id; }
       int id;
       friend ostream & operator << (ostream & out,const Widget & w)
          { return out << "Widget " << w.id; }
       friend bool operator == (const Widget& lhs, const Widget& rhs)
          { return lhs.id == rhs.id; }
       friend bool operator< (const Widget& lhs, const Widget& rhs)
          { return lhs.id < rhs.id; }
    };
    Stav zßsob je reprezentovßn dv∞ma seznamy. Jeden seznam reprezentuje stav za°φzenφ na sklad∞ zatφmco druh² seznam typy za°φzenφ ji₧ objednanΘ zßkaznφky. Prvnφ je seznam za°φzenφ, zatφmco druh² je seznamem identifikaΦnφch typ∙ za°φzenφ. Pro zpracovßnφ naÜich zßsob mßme dva p°φkazy: prvnφ order zpracovßvß objednßvky, zatφmco druh² receive zpracovßvß prodeje nov²ch za°φzenφ.
    class inventory {
    public:
       void order (int wid);     // zpracovßnφ objednßvky pro za°φzenφ typu wid
       void receive (int wid);   // p°φjem za°φzenφ typu wid v dodßvce
    private:
       list<Widget> on_hand;
       list<int> on_order;
    };
    Kdy₧ p°ijmeme novou dodßvku za°φzenφ, pak porovnßme identifikaΦnφ Φφsla za°φzenφ se seznamem ji₧ objednan²ch typ∙ za°φzenφ. Pro hledßnφ v ji₧ p°ijat²ch objednßvkßch pou₧ijeme find a bezprost°edn∞ prodßme objednanΘ za°φzenφ. Jinak za°φzanφ p°edßme na sklad.
    void inventory::receive (int wid)
    {
       cout << "Received shipment of widget type " << wid << endl;
       list<int>::iterator weneed =
          find (on_order.begin(), on_order.end(), wid);
       if (weneed != on_order.end())
       {
          cout << "Ship " << Widget(wid)
               << " to fill back order" << endl;
          on_order.erase(weneed);
       }
       else
          on_hand.push_front(Widget(wid));
    }
    Kdy₧ zßkaznφk objednßvß novΘ za°φzenφ, prohledßme seznam za°φzenφ na sklad∞ k urΦenφ zda objednßvku m∙₧eme vy°φdit okam₧it∞. K prohledßnφ seznamu pou₧ijeme funkci find_if. Pot°ebujeme k tomu binßrnφ funkci, kterß p°ebφrß jako sv∙j parametr za°φzenφ a urΦuje, zda za°φzenφ odpovφdß po₧adovanΘmu typu. M∙₧eme to provΘst p°edßnφm obecnΘ binßrnφ testovacφ funkce za°φzenφ a spojit druh² parametr na specifick² typ za°φzenφ. K pou₧itφ funkce bind2nd je zapot°ebφ, aby binßrnφ funkce byla instance t°φdy binary_function. NaÜi obecnou testovacφ funkci zapφÜeme takto:
    class WidgetTester : public binary_function<Widget, int, bool> {
    public:
       bool operator () (const Widget & wid, int testid) const
          { return wid.id == testid; }
    };
    Funkce order je pak zapsßna takto:
    void inventory::order (int wid)
    {
       cout << "Received order for widget type " << wid << endl;
       list<Widget>::iterator wehave =
             find_if (on_hand.begin(), on_hand.end(),
                bind2nd(WidgetTester(), wid));
       if (wehave != on_hand.end())
       {
          cout << "Ship " << *wehave << endl;
          on_hand.erase(wehave);
       }
       else
       {
          cout << "Back order widget of type "  << wid  << endl;
          on_order.push_front(wid);
       }
    }

  47. STL je mo₧no pou₧φvat i v C++ Builderu. Jako p°φklad pou₧itφ STL si ukß₧eme demonstraΦnφ aplikaci, kterß ukazuje °adu mo₧nostφ STL. Jednß se ji₧ op∞t o hotovou aplikaci. Stßhn∞te si ji a vyzkouÜejte. V aplikaci m∙₧ete zadat, co chcete vyzkouÜet a v²sledky jsou zobrazeny v komponent∞ Memo. Zajφmav∞jÜφ je ale podφvat se jak tyto ukßzky jsou naprogramovanΘ a sna₧it se pochopit, jak s touto knihovnou pracovat. Mezi soubory, kterΘ jste si stßhli jsou i p°φklady pou₧itΘ v p°edchozφm textu. SystΘm sprßvy inventß°e je v souboru widwork.cpp a program Eratosova sφta v souboru sieve.cpp. S dalÜφmi typy kontejner∙ se seznßmφme v nßsledujφcφ kapitole.
29. Knihovna standardnφch Üablon I