31. Knihovna standardnφch Üablon III
  1. Nynφ se podrobn∞ji seznßmφme se vÜemi obecn²mi algoritmy poskytnut²mi standardnφ knihovnou. JmΘna a krßtk² popis t∞chto algoritm∙ je uveden v nßsledujφcφ tabulce. Tyto algoritmy m∙₧eme rozd∞lit do n∞kolika kategoriφ, a to na zßklad∞ jejich obvyklΘho pou₧itφ.

  2.  
    JmΘno Popis
    Algoritmy pou₧φvanΘ k pln∞nφ sekvence
    fill Pln∞nφ sekvence poΦßteΦnφmi hodnotami.
    fill_n Pln∞nφ n pozic poΦßteΦnφ hodnotou.
    copy Kopφrovßnφ sekvence z jinΘ sekvence.
    copy_backward Kopφrovßnφ sekvence z jinΘ sekvence.
    generate Inicializuje sekvenci pomocφ generßtoru.
    generate_n Inicializuje n pozic pomocφ generßtoru.
    swap_ranges Zam∞≥uje hodnoty ve dvou paralelnφch sekvencφch.
    Vyhledßvacφ algoritmy
    find Hledßnφ prvku odpovφdajφcφmu parametru.
    find_if Hledßnφ prvku spl≥ujφcφho podmφnku.
    adjacent_find  Hledßnφ prvku shodujφcφho se s nßsledujφcφm prvkem.
    find_first_of Hledßnφ prvnφho v²skytu jednΘ sekvence v jinΘ sekvenci.
    find_end Hledßnφ poslednφho v²skytu podsekvence v sekvenci.
    search Hledßnφ podsekvence v sekvenci.
    max_element  Hledßnφ maximßlnφ hodnoty v sekvenci.
    min_element Hledßnφ minimßlnφ hodnoty v sekvenci.
    mismatch Nalezenφ prvnφ neshody v paralelnφch sekvencφch.
    Transformace na mφst∞
    reverse Obracφ prvky v sekvenci.
    replace Nahrazuje specifikovanΘ hodnoty novou hodnotou.
    replace_if  Nahrazuje prvky vyhovujφcφ tvrzenφ.
    rotate Rotuje prvky v sekvenci okolo bodu.
    partition Rozd∞luje prvky do dvou skupin.
    stable_partition Rozd∞lovßnφ chrßnφcφ p∙vodnφ po°adφ.
    next_permutation  Generuje permutaci v sekvenci.
    prev_permutation  Generuje permutaci v reverznφ sekvenci.
    inplace_merge Spojuje dv∞ sousednφ sekvence v jednu.
    random_shuffle Nßhodn∞ p°eskupφ prvky v sekvenci.
    Odstra≥ovacφ algoritmy
    remove Odstra≥uje prvky spl≥ujφcφ podmφnku.
    unique Odstra≥uje vÜechny neprvnφ duplicitnφ hodnoty v sekvenci.
    Algoritmy generujφcφ skalßr
    count PoΦet prvk∙ s odpovφdajφcφ hodnotou.
    count_if PoΦet prvk∙ vyhovujφcφch tvrzenφ.
    accumulate Redukce sekvence na skalßrnφ hodnotu.
    inner_product  Vnit°nφ produkt dvou paralelnφch sekvencφ.
    equal Test dvou sekvencφ na rovnost.
    lexicographical_compare Porovnßvßnφ dvou sekvencφ.
    Algoritmy generujφcφ sekvence
    transform Transformuje ka₧d² prvek.
    partial_sum Generuje sekvenci ΦßsteΦn²ch souΦt∙.
    adjacent_difference Generuje sekvenci sousednφch rozdφl∙.
    R∙znΘ operace
    for_each Aplikuje funkci na ka₧d² prvek kolekce.

    Pro pou₧itφ v∞tÜiny obecn²ch algoritm∙ musφme vlo₧it p°φsluÜn² hlaviΦkov² soubor. Hlavnφ funkce jsou definovßny v hlaviΦkovΘm souboru algorithm. Funkce accumulate, inner_product, partial_sum a adjacent_difference jsou definovßny v hlaviΦkovΘm souboru numeric.
    # include <algorithm>
    # include <numeric>

  3. Prvnφ skupinou algoritm∙, kter²mi se budeme zab²vat jsou algoritmy pou₧φvanΘ k inicializaci nov∞ vytvo°en²ch sekvencφ jist²mi hodnotami. Standardnφ knihovna poskytuje n∞kolik inicializaΦnφch algoritm∙.

  4. Algoritmy fill a fill_n jsou pou₧φvßny k inicializaci nebo reinicializaci sekvence pevnou hodnotou. Jejich deklarace jsou tyto:
    void fill (ForwardIterator first, ForwardIterator last, const T&);
    void fill_n (OutputIterator, Size, const T&);
    P°φklad programu ukazujφcφ pou₧itφ t∞chto algoritm∙:
    void fill_example ()
    {
       // p°φklad 1, zapln∞nφ pole poΦßteΦnφmi hodnotami
       char buffer[100], * bufferp = buffer;
       fill (bufferp, bufferp + 100, '\0');
       fill_n (bufferp, 10, 'x');
       // p°φklad 2, inicializace seznamu
       list<string> aList(5, "nothing");
       fill_n (inserter(aList, aList.begin()), 10, "empty");
       // p°φklad 3, p°epsßnφ hodnot v seznamu
       fill (aList.begin(), aList.end(), "full");
       // p°φklad 4, zapln∞nφ Φßsti kolekce
       vector<int> iVec(10);
       generate (iVec.begin(), iVec.end(), iotaGen(1));
       vector<int>::iterator & seven = find(iVec.begin(), iVec.end(), 7);
       fill (iVec.begin(), seven, 0);
    }
    V p°φkladu 1 je deklarovßno pole znak∙. Algoritmus fill je vyvolßn k inicializaci ka₧dΘ pozice v poli znakem s k≤dem 0. Dßle je prvnφch 10 pozic p°epsßno znakem x pomocφ algoritmu fill_n. PovÜimn∞te si, ₧e fill pou₧φvß jako parametry zaΦßteΦnφ a koncov² iterßtor, zatφmco fill_n pou₧φvß poΦßteΦnφ iterßtor a poΦet.
    P°φklad 2 ukazuje, jak pou₧itφm vklßdacφho iterßtoru m∙₧e b²t algoritmus fill_n pou₧it k inicializaci kontejneru prom∞nnΘ dΘlky, jako je seznam. V tomto p°φpad∞ seznam p∙vodn∞ obsahuje 5 prvk∙, vÜechny s textem nothing. Volßnφ fill_n pak vklßdß 10 instancφ °et∞zce empty. V²sledn² seznam obsahuje 15 prvk∙.
    T°etφ a Φtvrt² p°φklad ukazuje, jak fill m∙₧e b²t pou₧ito ke zm∞n∞ hodnot v existujφcφ kontejneru. Ve t°etφm p°φklad∞ je ka₧d² z patnßcti prvk∙ vytvo°en²ch v druhΘm p°φklad∞ nahrazen °et∞zcem full.
    P°φklad 4 p°episuje pouze Φßst seznamu. Pomocφ algoritmu generate (bude popsßn dßle) a objektu funkce iotaGen je vektor inicializovßn hodnotami 1 2 3 ... 10. Algoritmus find je pak pou₧it k zjiÜt∞nφ pozice prvku 7 a ulo₧enφ mφsta do iterßtoru p°φsluÜnΘho typu pro datov² typ vektor. Volßnφ fill pak nahradφ vÜechny a₧ po (ale ne vΦetn∞) 7 hodnotami 0. V²sledn² vektor mß Üest nul nßsledovan²ch hodnotami 7, 8, 9 a 10.
    fill a fill_n mohou b²t pou₧ity se vÜemi t°φdami kontejner∙ ve standardnφ knihovn∞, aΦkoliv s °azen²mi kontejnery, jako jsou mno₧iny, musφ b²t pou₧ity vklßdacφ iterßtory.
    Algoritmy copy a copy_backward jsou p°izp∙sobivΘ funkce, kterΘ mohou b²t pou₧ity pro mnoho r∙zn²ch ·Φel∙ a jsou pravd∞podobn∞ nejΦast∞ji pou₧φvan²mi algoritmy ze standardnφ knihovny. Deklarace pro tyto algoritmy jsou:
    OutputIterator copy (InputIterator first, InputIterator last,
             OutputIterator result);
    BidirectionalIterator copy_backward (BidirectionalIterator first,
             BidirectionalIterator last, BidirectionalIterator result);
    Pou₧itφ algoritmu copy zahrnuje: Je to ukßzßno v nßsledujφcφm p°φklad∞ programu.
    void copy_example()
    {
       char * source = "reprise";
       char * surpass = "surpass";
       char buffer[120], * bufferp = buffer;
       // p°φklad 1, jednoduchß kopie
       copy (source, source + strlen(source) + 1, bufferp);
       // p°φklad 2, kopie do sebe sama
       copy (bufferp + 2, bufferp + strlen(buffer) + 1, bufferp);
       int buflen = strlen(buffer) + 1;
       copy_backward (bufferp, bufferp + buflen, bufferp + buflen + 3);
       copy (surpass, surpass + 3, bufferp);
       // p°φklad 3, kopφrovßnφ na v²stup
       copy (bufferp, bufferp + strlen(buffer),
                ostream_iterator<char,char>(cout));
       cout << endl;
       // p°φklad 4, pou₧itφ kopφrovßnφ pro p°evod typu
       list<char> char_list;
       copy (bufferp, bufferp + strlen(buffer),
                inserter(char_list, char_list.end()));
       char * big = "big ";
       copy (big, big + 4, inserter(char_list, char_list.begin()));
       char buffer2 [120], * buffer2p = buffer2;
       * copy (char_list.begin(), char_list.end(), buffer2p) = '\0';
       cout << buffer2 << endl;
    }
    Volßnφ copy v p°φklad∞ 1, pouze kopφruje °et∞zec obsa₧en² v prom∞nnΘ source do vyrovnßvacφ pam∞ti buffer (v²sledkem je, ₧e buffer obsahuje text "reprise"). PovÜimn∞te si, ₧e koncovß pozice pro kopφrovßnφ je znak p°edchßzejφcφ nulov² ukonΦujφcφ znak, a tedy znak NULL nenφ zahrnut do operace kopφrovßnφ.
    Operace copy je specißln∞ urΦena k provßd∞nφ kopie sekvence do sebe sama. To ukazuje p°φklad 2. Kopφrujeme od pozice 2 buffer a pokraΦujeme do konce, p°iΦem₧ kopφrovanΘ znaky vklßdßme od poΦßtku buffer. V²sledkem je, ₧e buffer obsahuje "prise".
    Druhß polovina p°φkladu 2 ukazuje pou₧itφ algoritmu copy_backward. Tato funkce provßdφ stejnΘ ·koly jako algoritmus copy, ale p°esouvß prvky od konce sekvence k zaΦßtku (pokud parametr je °et∞zec, pak znaky jsou p°esouvßny poΦφnaje odprava a zpracovßvßny vlevo). V tomto p°φpad∞ v²sledkem je, ₧e buffer bude obsahovat hodnotu "priprise". Prvnφ t°i znaky jsou pak modifikovßny dalÜφ operacφ copy na hodnoty "sur" a v²sledkem je, ₧e buffer obsahuje "surprice".
    P°φklad 3 ukazuje copy pou₧itΘ k p°esunu hodnot do v²stupnφho proudu. Cφlem je v tomto p°φpad∞ ostream_iterator generovan² pro v²stupnφ proud cout. Podobn² mechanismus m∙₧e b²t pou₧it pro vstup hodnot. Nap°. jednoduch²m mechanismem pro kopφrovßnφ ka₧dΘho slova ze vstupnφho proudu do seznamu je nßsledujφcφ volßnφ copy:
    list<string> words;
    istream_iterator<string, char> in_stream(cin), eof;
    copy(in_stream, eof, inserter(words, words.begin()));
    Tato technika byla pou₧ita v programu kontroly pravopisu.
    copy m∙₧e b²t takΘ pou₧ito pro p°evod z jednoho typu proudu na jin². Nap°. volßnφ v p°φkladu 4 kopφruje znaky dr₧enΘ v buffer po jednom do seznamu znak∙. Volßnφ na inserter vytvß°φ vklßdacφ iterßtor, pou₧it² k vklßdßnφ hodnot do seznamu. Prvnφ volßnφ copy umφs¥uje °et∞zec surprice vytvo°en² v p°φkladu 2 do seznamu. DruhΘ volßnφ copy vklßdß hodnoty z °et∞zce "big " na zaΦßtek seznamu a seznam obsahuje znaky big surprise. Poslednφ volßnφ copy ukazuje opaΦn² proces, kopφrovßnφ znak∙ ze seznamu zp∞t do znakovΘ vyrovnßvacφ pam∞ti.
    Generßtor je funkce, kterß vracφ °adu hodnot. Pravd∞podobn∞ nejznßm∞jÜφm generßtorem je generßtor nßhodn²ch Φφsel. Generßtory ale mohou b²t vytvß°eny pro r∙znΘ ·Φely, vΦetn∞ inicializacφ sekvencφ.
    Podobn∞ jako fill a fill_n jsou algoritmy generate a generate_n pou₧φvßny k inicializaci nebo reinicializaci sekvence. Deklarace t∞chto algoritm∙ je tato:
    void generate (ForwardIterator, ForwardIterator, Generator);
    void generate_n (OutputIterator, Size, Generator);
    NßÜ p°φklad ukazuje n∞kolik pou₧itφ algoritmu generate k inicializaci sekvence.
    string generateLabel () {
       // generovßnφ  popis∙ unikßtnφch °et∞zc∙ tvaru L_ddd
       static int lastLabel = 0;
       char labelBuffer[80];
       ostrstream ost(labelBuffer, 80);
       ost << "L_" << lastLabel++ << '\0';
       return string(labelBuffer);
    }
    void generate_example ()
    {
       // p°φklad 1, generovßnφ seznamu popis∙
       list<string> labelList;
       generate_n (inserter(labelList, labelList.begin()), 4, generateLabel);
       // p°φklad 2, generovßnφ Φφseln²ch hodnot
       vector<int> iVec(10);
       generate (iVec.begin(), iVec.end(), iotaGen(2));
       generate_n (iVec.begin(), 5, iotaGen(7));
    }
    Generßtor m∙₧e b²t vytvo°en jako jednoduchß funkce, kterß si pamatuje informace o svΘ p°edchozφ historii v jednΘ nebo vφce statick²ch prom∞nn²ch. V naÜem p°φkladu je to funkce generateLabel. Tato funkce vytvß°φ sekvenci unikßtnφch °et∞zc∙ popis∙. Ka₧dΘ volßnφ fukce generateLabel vracφ nov² °et∞zec tvaru L_ddd, ka₧d² s unikßtnφ Φφselnou hodnotou. Proto₧e prom∞nnß nazvanß lastLabel je deklarovanß jako statickß, jejφ hodnota je zapamatovßna z p°edchozφho vyvolßnφ. V p°φklad∞ 1 je tato funkce pou₧ita v kombinaci s algoritmem generate_n k inicializaci seznamu Φty°mi hodnotami popisu.
    Jak ji₧ bylo uvedeno, funkce je libovoln² objekt, kter² odpovφdß na operßtor volßnφ funkce. Pomocφ tohoto faktu, mohou b²t t°φdy snadno vytvo°eny jako funkce. P°φkladem je ji₧ d°φve popsanß funkce iotaGen. Objekt funkce iotaGen vytvß°φ generßtor pro celoΦφselnou aritmetickou sekvenci. V p°φklad∞ 2 v naÜem programu je tato sekvence pou₧ita k inicializaci vektoru celoΦφseln²mi hodnotami od 2 do 11. Volßnφ generate_n je pak pou₧ito k p°epsßnφ prvnφch 5 pozic vektoru hodnotami 7 a₧ 11, Φφm₧ v²sledn² vektor je 7 8 9 10 11 7 8 9 10 11.
    èablona funkce swap m∙₧e b²t pou₧ita k v²m∞n∞ hodnot dvou objekt∙ stejnΘho typu. Mß nßsledujφcφ definici:
    template <class T> void swap (T& a, T& b)
    {
       T temp(a);
       a = b;
       b = temp;
    }
    Funkce je zobecn∞na na iterßtory ve funkci nazvanΘ iter_swap. Algoritmus swap_ranges pak toto rozÜi°uje na celΘ sekvence. Hodnoty urΦenΘ prvnφ sekvencφ jsou zam∞n∞ny s hodnotami urΦen²mi druhou paralelnφ sekvencφ. Prototyp algoritmu swap_ranges je tento:
    ForwardIterator swap_ranges (ForwardIterator first,
             ForwardIterator last, ForwardIterator first2);
    Druh² rozsah je popsßn pouze poΦßteΦnφm iterßtorem. P°edpoklßdß se (ale nenφ ov∞°ovßno), ₧e druh² rozsah mß alespo≥ tolik prvk∙ jako prvnφ rozsah. Pou₧itφ obou funkcφ vidφme v nßsledujφcφm programu.
    void swap_example ()
    {
       // nejprve vytvo°φme dv∞ paralelnφ sekvence
       int data[] = {12, 27, 14, 64}, *datap = data;
       vector<int> aVec(4);
       generate(aVec.begin(), aVec.end(), iotaGen(1));
       // pou₧itφ swap a iter_swap
       swap(data[0], data[2]);
       vector<int>::iterator last = aVec.end(); last--;
       iter_swap(aVec.begin(), last);
       // v²m∞na cel²ch sekvencφ
       swap_ranges (aVec.begin(), aVec.end(), datap);
    }
  5. Vyhledßvacφ rutiny popsanΘ v tomto bod∞ vracφ iterßtor, kter² urΦuje prvnφ prvek odpovφdajφcφ vyhledßvacφ podmφnce. Tuto hodnotu obecn∞ uklßdßme do prom∞nnΘ iterßtoru takto:

  6. list<int>::iterator where;
    where = find(aList.begin(), aList.end(), 7);
    Jestli₧e chceme lokalizovat vÜechny prvky, kterΘ spl≥ujφ vyhledßvacφ podmφnku, pak musφme zapsat cyklus. Nap°. nßsledujφcφ cyklus z p°φkladu programu adjacent_find (viz dßle) vypisuje hodnoty vÜech opakujφcφch se znak∙ v °et∞zci.
    while ((where = adjacent_find(where, stop)) != stop) {
      cout << "double " << *where << " in position "
           << where - start << endl;
      ++where;
    }
    Mnoho vyhledßvacφch algoritm∙ mß voliteln² parametr, kter² m∙₧e specifikovat funkci pou₧itou k porovnßvßnφ prvk∙ (mφsto operßtoru == pro typ prvku kontejneru). V popisu algoritm∙ budeme zapisovat voliteln² parametr do hranat²ch zßvorek k indikaci, ₧e nemusφ b²t specifikovßn, pokud standardnφ operßtor rovnosti je vyhovujφcφ.
    Jsou dva algoritmy find a find_if, kterΘ jsou pou₧itelnΘ k nalezenφ prvnφho prvku, kter² spl≥uje podmφnku. Deklarace t∞chto dvou algoritm∙ je tato:
    InputIterator find_if(InputIterator first,InputIterator last,Predicate);
    InputIterator find(InputIterator first,InputIterator last,const T&);
    Algoritmus find_if p°ebφrß funkci tvrzenφ (libovolnou funkci vracejφcφ logickou hodnotu). Algoritmus find_if vracφ nov² iterßtor, kter² urΦuje prvnφ prvek v sekvenci spl≥ujφcφ tvrzenφ. Druh² parametr je iterßtor urΦujφcφ konec a je vrßcen, pokud ₧ßdn² prvek nespl≥uje po₧adavek. Proto₧e v²slednß hodnota je iterßtor, musφ b²t pou₧it operßtor dereference k zφskßnφ hledanΘ hodnoty.
    Druh² tvar algoritmu find nahrazuje funkci tvrzenφ specifikovanou hodnotou a vracφ prvnφ prvek, kter² je roven tΘto hodnot∞ (pou₧itφm operßtoru == pro dan² datov² typ). Nßsledujφcφ p°φklad ukazuje pou₧itφ t∞chto algoritm∙.
    void find_test ()
    {
       int vintageYears[] = {1967, 1972, 1974, 1980, 1995};
       int * start = vintageYears;
       int * stop = start + 5;
       int * where = find_if (start, stop, isLeapYear);
       if (where != stop)
          cout << "first vintage leap year is " << *where << endl;
       else
          cout << "no vintage leap years" << endl;
       where = find(start, stop, 1995);
       if (where != stop)
          cout << "1995 is position " << where - start
             << " in sequence" << endl;
       else cout "1995 does not occur in sequence" << endl;
    }
    Algoritmus adjacent_find je pou₧it k nalezenφ prvnφch prvk∙ v sekvenci rovn²ch bezprost°edn∞ nßsledujφcφmu prvku. Nap°. pokud sekvence obsahuje hodnoty 1 4 2 5 6 6 7 5, pak algoritmus vracφ iterßtor ukazujφcφ na prvnφ hodnotu 6. Pokud nenφ nalezena vyhovujφcφ hodnota, pak je vrßcen iterßtor koncovΘ hodnoty. Deklarace algoritmu je tato:
    ForwardIterator adjacent_find (ForwardIterator first,
       ForwardIterator last [, BinaryPredicate ] );
    Prvnφ dva parametry specifikujφ zkoumanou sekvenci. Voliteln² t°etφ parametr musφ b²t funkce tvrzenφ.
    Nßsledujφcφ p°φklad prohledßvß textov² °et∞zec na sousednφ pφsmena. V pou₧itΘm textu je nalezena shoda na pozicφch 5, 7, 9, 21 a 37. Uvnit° cyklu je nutno provΘst inkrementaci, abychom stejnou pozici nenaÜli opakovan∞.
    void adjacent_find_example ()
    {
       char * text = "The bookkeeper carefully opened the door.";
       char * start = text;
       char * stop = text + strlen(text);
       char * where = start;
       cout << "In the text: " << text << endl;
       while ((where = adjacent_find(where, stop)) != stop) {
          cout << "double " << *where
             << " in position " << where - start << endl;
          ++where;
       }
    }
    Algoritmus find_first_of je pou₧it k nalezenφ prvnφho v²skytu n∞jakΘho prvku z jednΘ sekvence, kterß je takΘ obsa₧ena v jinΘ sekvenci.
    ForwardIterator1 find_first_of (ForwardIterator1 first1,
             ForwardIterator1 last1, ForwardIterator2 first2,
             ForwardIterator2 last2 [, BinaryPredicate pred ] );
    Algoritmus vracφ nov² iterßtor, kter² urΦuje prvnφ prvek nalezen² v <first1,last1), kter² je takΘ obsa₧en v <first2,last2). Pokud je hledßnφ ne·sp∞ÜnΘ, pak je vrßcen druh² parametr. Proto₧e vrßcenß hodnota je iterßtor, musφ b²t pou₧it operßtor dereference k zφskßnφ nalezenΘ hodnoty. Ukazuje to nßsledujφcφ program:
    void find_test ()
    {
       int vintageYears[] = {1967, 1972, 1974, 1980, 1995};
       int requestedYears[] = [1923, 1970, 1980, 1974 };
       int * start = vintageYears;
       int * stop = start + 5;
       int * where = find_first_of (start, stop,
                               requestedyears,requestedyears+4 );
       if (where != stop)
          cout << "first requested vintage year is " << *where << endl;
       else cout << "no requested vintage years" << endl;
    }
    PovÜimn∞te si, ₧e tento algoritmus, na rozdφl od mnoha jin²ch pracujφcφch se dv∞mi sekvencemi, pou₧φvß poΦßteΦnφ i koncov² iterßtor pro ob∞ sekvence a nejen pro prvnφ sekvenci.
    Alternativnφ verze find_first_of, algoritmy equal a mismatch p°ebφrajφ volitelnou funkci tvrzenφ, kterß je pou₧ita k porovnßvßnφ prvk∙ ze dvou sekvencφ.
    Algoritmy search a search_n jsou pou₧φvßny k lokalizaci zaΦßtku jistΘ podsekvence ve v∞tÜφ sekvenci. Jednß se v podstat∞ o problΘm hledßnφ jistΘho pod°et∞zce v delÜφm °et∞zci. O parametrech se p°edpoklßdß, ₧e majφ alespo≥ schopnosti dop°edn²ch iterßtor∙.
    ForwardIterator search (ForwardIterator first1,
       ForwardIterator last1, ForwardIterator first2,
       ForwardIterator last2 [, BinaryPredicate ]);
    P°edpoklßdejme nap°. ₧e chceme nalΘzt umφst∞nφ °et∞zce "ration" v °et∞zci "dreams and aspirations". ╪eÜenφ tohoto problΘmu je ukßzßno v nßsledujφcφm programu. Pokud je hledßnφ ne·sp∞ÜnΘ, pak je vrßcen iterßtor koncovΘ hodnoty prvnφ sekvence.
    void search_example ()
    {
       char * base = "dreams and aspirations";
       char * text = "ration";
       char * where = search(base, base + strlen(base),
             text, text + strlen(text));
       if (*where != '\0')
          cout << "substring position: " << where - base << endl;
       else cout << "substring does not occur in text" << endl;
    }
    Algoritmus find_end je pou₧it k lokalizaci zaΦßtku poslednφho v²skytu jistΘ podsekvence ve v∞tÜφ sekvenci.
    ForwardIterator find_end (ForwardIterator first1,
       ForwardIterator last1, ForwardIterator first2,
       ForwardIterator last2 [, BinaryPredicate ]);
    P°edpoklßdejme, ₧e chceme nalΘzt poslednφ v²skyt °et∞zce "le" v °et∞zci "The road less traveled". ╪eÜenφ vidφme v nßsledujφcφm programu.
    void find_end_example ()
    {
       char * base = "The road less traveled";
       char * text = "le";
       char * where = find(base, base + strlen(base),
             text, text + strlen(text));
       if (*where != '\0')
          cout << "substring position: " << where - base << endl;
       else cout << "substring does not occur in text" << endl;
    }
    Funkce max a min mohou b²t pou₧ity k nalezenφ maximßlnφ a minimßlnφ hodnoty z dvojice hodnot. Voliteln∞ m∙₧e b²t poskytnut t°etφ parametr, kter² definuje porovnßvacφ funkci pou₧itou mφsto operßtoru <. Parametry jsou hodnoty a ne iterßtory:
    template <class T> const T& max(const T& a, const T& b[, Compare ]);
    template <class T> const T& min(const T& a, const T& b[, Compare ]);
    Tyto funkce jsou zobecn∞ny na celΘ sekvence obecn²mi algoritmy max_element a min_element. Pro tyto funkce jsou parametry vstupnφ iterßtory.
    ForwardIterator max_element (ForwardIterator first,
          ForwardIterator last [, Compare ] );
    ForwardIterator min_element (ForwardIterator first,
          ForwardIterator last [, Compare ] );
    Tyto algoritmy vracφ iterßtor, kter² urΦuje nejv∞tÜφ nebo nejmenÜφ hodnotu v sekvenci. Pokud po₧adavek spl≥uje vφce ne₧ jedna hodnota, pak je vrßcena prvnφ vyhovujφcφ hodnota. Oba algoritmy mohou voliteln∞ pou₧φvat t°etφ parametr, kter²m je funkce pou₧itß jako porovnßvacφ operßtor.
    Pou₧itφ t∞chto algoritm∙ ukazuje nßsledujφcφ program. Funkce nazvanß split se pou₧φvß k rozd∞lenφ °et∞zce na slova.
    void max_min_example ()
    {
       // vytvo°enφ vektoru nßhodn²ch Φφsel mezi 0 a 99
       vector<int> numbers(25);
       for (int i = 0; i < 25; i++)
          numbers[i] = randomInteger(100);
       // v²pis maxima
       vector<int>::iterator max =
          max_element(numbers.begin(), numbers.end());
       cout << "largest value was " << * max << endl;
       // p°φklad pou₧φvajφcφ °et∞zce
       string text="It was the best of times, it was the worst of times.";
       list<string> words;
       split (text, " .,!:;", words);
       cout << "The smallest word is "
             << * min_element(words.begin(), words.end())
             << " and the largest word is "
             << * max_element(words.begin(), words.end()) << endl;
    }
    JmΘno mismatch nßm °φkß, ₧e se jednß o inverzi algoritmu equal. Algoritmus mismatch vracφ dvojici iterßtor∙, kterΘ urΦujφ prvnφ pozici, kde dv∞ paralelnφ sekvence majφ r∙znΘ prvky. Druhß sekvence je urΦena pouze poΦßteΦnφ pozicφ. P°edpoklßdß se (ale nenφ testovßno), ₧e druhß sekvence obsahuje alespo≥ tolik prvk∙ jako prvnφ. Parametry a nßvratov² typ mohou b²t popsßny takto:
    pair<InputIterator, InputIterator> mismatch (InputIterator first1,
      InputIterator last1, InputIterator first2 [, BinaryPredicate ] );
    Prvky dvou sekvencφ jsou zkoumßny paraleln∞, prvek po prvku. Kdy₧ je nalezena neshoda, tj. bod, kde se dv∞ sekvence liÜφ, pak je pßr obsahujφcφ iterßtory urΦujφcφ mφsta dvou liÜφcφch se prvk∙ vytvo°en a vrßcen. Pokud prvnφ sekvence skonΦφ bez nalezenφ neshody, pak vrßcen² pßr obsahuje konΦφcφ hodnotu prvnφ sekvence a poslednφ zkoumanou hodnotu druhΘ sekvence.
    P°φklad ukazuje pou₧itφ tΘto procedury. Funkce mismatch_test p°ebφrß jako parametry dva °et∞zce. Jsou lexikograficky porovnßvßny a je vypsßna zprßva indikujφcφ jejich relativnφ po°adφ. Proto₧e algoritmus mismatch p°edpoklßdß, ₧e druhß sekvence je alespo≥ tak dlouhß jako prvnφ, pak d°φve ne₧ je provedeno porovnßvßnφ kdy₧ druh² °et∞zec je kratÜφ, jsou parametry algoritnu vym∞n∞ny. Vracen² pßr iterßtor∙ je po ukonΦenφ volßnφ mismatch pou₧it k urΦenφ p°φsluÜnΘho po°adφ.
    void mismatch_test (char * a, char * b)
    {
      pair<char *, char *> differPositions(0, 0);
      char * aDiffPosition;
      char * bDiffPosition;
      if (strlen(a) < strlen(b)) {
        // zajiÜt∞nφ, ₧e druh² parametr je delÜφ
        differPositions = mismatch(a, a + strlen(a), b);
        aDiffPosition = differPositions.first;
        bDiffPosition = differPositions.second;
      }
      else {
        differPositions = mismatch(b, b + strlen(b), a);
        aDiffPosition = differPositions.second;
        bDiffPosition = differPositions.first;
      }
      // porovnßnφ vrßcen²ch hodnot
      cout << "string " << a;
      if (*aDiffPosition == *bDiffPosition)
        cout << " is equal to ";
      else if (*aDiffPosition < *bDiffPosition)
        cout << " is less than ";
      else cout << " is greater than ";
      cout << b << endl;
    }
  7. Nßsledujφcφ kategorie algoritm∙ je pou₧φvßna k modifikaci a transformaci sekvence bez jejφho p°esunu z jejφho p∙vodnφho mφsta ulo₧enφ. N∞kterΘ z nich, jako je replace, zahrnujφ takΘ kopφrovacφ verzi. Pro ostatnφ, pokud chceme zachrßnit originßl, si pak musφme vytvo°it kopii p°ed zahßjenφm transformace. Nap°. nßsleduje ukßzka otoΦenφ vektoru do nov∞ alokovanΘho vektoru.

  8. vector<int> newVec(aVec.size());
    copy (aVec.begin(), aVec.end(), newVec.begin()); // nejprve kopie
    reverse (newVec.begin(), newVec.end());          // pak otoΦenφ
    Algoritmus reverse obracφ prvky v sekvenci. Poslednφ prvek se stane prvnφm a prvnφ poslednφm. Parametry musφ b²t obousm∞rnΘ iterßtory a ₧ßdnß hodnota nenφ vrßcena.
    void reverse(BidirectionalIterator first,BidirectionalIterator last);
    Nßsledujφcφ p°φklad ukazuje dv∞ pou₧itφ tohoto algoritmu. V prvnφm je otoΦeno pole znak∙. Algoritmus reverse m∙₧e b²t takΘ pou₧it na seznamu hodnot, jak je ukßzßno v druhΘm p°φklad∞ (je zde pou₧it seznam hodnot 2 a₧ 11).
    void reverse_example ()
    {
      // p°φklad 1, obracenφ °et∞zce
      char * text = "Rats live on no evil star";
      reverse (text, text + strlen(text));
      cout << text << endl;
      // p°φklad 2, obracenφ seznamu
      list<int> iList;
      generate_n (inserter(iList, iList.begin()), 10, iotaGen(2));
      reverse (iList.begin(), iList.end());
    }
    Algoritmy replace a replace_if jsou pou₧φvßny k nahrazenφ v²skyt∙ jist²ch prvk∙ novou hodnotou. V obou p°φpadech je novß hodnota stejnß a nezßle₧φ na poΦtu proveden²ch nahrazenφ. Parametry iterßtor∙ musφ b²t dop°ednΘ iterßtory.
    Algoritmy replace_copy a replace_copy_if jsou si podobnΘ, ale ponechajφ p∙vodnφ sekvenci nezm∞n∞nou a v²slednß sekvence je umφst∞na do novΘ sekvence, kterß m∙₧e b²t jinΘho typu.
    void replace (ForwardIterator first, ForwardIterator last,
             const T&, const T&);
    void replace_if (ForwardIterator first, ForwardIterator last,
             Predicate, const T&);
    OutputIterator replace_copy (InputIterator, InputIterator,
             OutputIterator, const T&, const T&);
    OutputIterator replace_copy (InputIterator, InputIterator,
             OutputIterator, Predicate, const T&);
    V p°φkladu, vektoru jsou p∙vodn∞ p°i°azeny hodnoty  0 1 2 3 4 5 4 3 2 1 0. Volßnφ replace nahradφ hodnotu 3 hodnotou 7 a dostaneme 0 1 2 7 4 5 4 7 2 1 0. Vyvolßnφ replace_if nahradφ dßle vÜechny sudΘ hodnoty Φφslem 9 a dosaneme 9 1 9 7 9 5 9 7 9 1 9.
    void replace_example ()
    {
       // vytvo°enφ vektoru 0 1 2 3 4 5 4 3 2 1 0
       vector<int> numbers(11);
       for (int i = 0; i < 11; i++)
          numbers[i] = i < 5 ? i : 10 - i;
       // nahrazenφ 3 hodnotou 7
       replace (numbers.begin(), numbers.end(), 3, 7);
       // nahrazenφ sud²ch hodnot hodnotou 9
       replace_if (numbers.begin(), numbers.end(), isEven, 9);
       // pou₧itφ kopφrovacφ verze replace
       int aList[] = {2, 1, 4, 3, 2, 5};
       int bList[6], cList[6], j;
       replace_copy (aList, aList+6, &bList[0], 2, 7);
       replace_copy_if (bList, bList+6, &cList[0],
             bind2nd(greater<int>(), 3), 8);
    }
    P°φklad takΘ ukazuje pou₧itφ algoritmu replace_copy. Nejprve je vytvo°eno pole s hodnotami 2 1 4 3 2 5. Pak nahradφme 2 hodnotou 7 a dostaneme  7 1 4 3 7 5. Dßle vÜechny hodnoty v∞tÜφ ne₧ 3 jsou nahrazeny hodnotou 8 a dostaneme  8 1 8 3 8 8.  V poslednφm p°φpad∞ pou₧ijeme adaptΘr bind2nd ke spojenφ funkce greater s konstantou 3, tj. vytvo°enφ unßrnφ funkce x > 3.
    Rotace sekvence rozd∞luje sekvenci na dv∞ Φßsti, a pak jsou tyto Φßsti zam∞n∞ny, p°iΦem₧ relativnφ po°adφ prvk∙ v Φßstech je zachovßno. P°edpoklßdejme nap°. ₧e mßme sekvenci hodnot 1 a₧ 10.
    1 2 3 4 5 6 7 8 9 10
    Pokud provßdφme rotaci okolo prvku 7, pak hodnoty 7 a₧ 10 jsou p°esunuty na zaΦßtek. V²sledkem je
    7 8 9 10 1 2 3 4 5 6
    P°i vyvolßnφ algoritmu rotate p°edßvßme iterßtory zaΦßtku, bodu rotace a konce. Musφ to b²t dop°ednΘ iterßtory.
    void rotate (ForwardIterator first, ForwardIterator middle,
       ForwardIterator last);
    Nßsleduje ukßzka pou₧itφ algoritmu.
    void rotate_example()
    {
       // vytvo°enφ seznamu 1 2 3 ... 10
       list<int> iList;
       generate_n(inserter(iList, iList.begin()), 10, iotaGen(1));
       // nalezenφ mφsta 7
       list<int>::iterator & middle=find(iList.begin(),iList.end(),7);
       // rotace okolo tohoto mφsta
       rotate (iList.begin(), middle, iList.end());
       // op∞t rotace okolo stejnΘho mφsta
       list<int> cList;
       rotate_copy (iList.begin(), middle, iList.end(),
          inserter(cList, cList.begin()));
    }
    rotate_copy kopφruje prvky do novΘ sekvence. Rotujeme okolo stejnΘho bodu, kter²m je nynφ hodnota 3 a dostaneme 3 4 5 6 7 8 9 10 1 2. Hodnoty ulo₧enΘ v iList z∙stßvajφ nezm∞n∞ny.
    Rozd∞lovßnφ je p°esun vÜech prvk∙ spl≥ujφcφch tvrzenφ na jeden konec sekvence a prvk∙ nespl≥ujφcφch tvrzenφ na druh² konec sekvence. Je to zßkladnφ krok n∞kter²ch °adφcφch algoritm∙, jako "quicksort".
    BidirectionalIterator partition
       (BidirectionalIterator, BidirectionalIterator, Predicate);
    BidirectionalIterator stable_partition
       (BidirectionalIterator, BidirectionalIterator, Predicate);
    Jsou dv∞ formy rozd∞lovßnφ podporovanΘ standardnφ knihovnou. Prvnφ, poskytnutß algoritmem partition zajiÜ¥uje pouze to, ₧e prvky jsou rozd∞leny do dvou skupin. V²slednß hodnota je iterßtor, kter² urΦuje bod mezi skupinami.
    V nßsledujφcφm p°φklad∞ vektor s hodnotami 1 a₧ 10 rozd∞lφme tak, ₧e p°esuneme sudΘ hodnoty na zaΦßtek a lichΘ na konec. Iterßtor st°edu ukazuje na hodnotu 5.
    void partition_example ()
    {
       // vytvo°enφ vektoru 1 2 3 ... 10
       vector<int> numbers(10);
       generate(numbers.begin(), numbers.end(), iotaGen(1));
       // p°esun sud²ch dop°edu a lich²ch dozadu
       vector<int>::iterator result =
          partition(numbers.begin(), numbers.end(), isEven);
       cout << "middle location " << result - numbers.begin() << endl;
       // nßsleduje stabilnφ rozd∞lenφ
       generate (numbers.begin(), numbers.end(), iotaGen(1));
       stable_partition (numbers.begin(), numbers.end(), isEven);
    }
    Relativnφ po°adφ prvk∙ v Φßsti ve v²slednΘm vektoru nemusφ b²t stejnΘ jako u p∙vodnφho vektoru. Nap°. hodnota 4 v p∙vodnφm poli p°edchßzφ 8, zatφmco v rozd∞lenΘm poli jej nßsleduje. Druhß verze nazvanß stable_partition, zajiÜ¥uje zachovßnφ po°adφ v²sledn²ch hodnot (stabilnφ rozd∞lovßnφ). Pro nßÜ p°φklad tedy dostaneme 2 4 6 8 10 1 3 5 7 9.
    Permutace je p°emφs¥ovßnφ hodnot. Pokud hodnoty jsou porovnatelnΘ s jin²mi (jako jsou celß Φφsla, znaky nebo slova), pak je mo₧nΘ systematicky vytvo°it vÜechny permutace sekvence. Jsou dv∞ permutace dvou hodnot, 6 permutacφ t°φ hodnot a 24 permutacφ 4 hodnot. Algoritmy definujφcφ permutace majφ nßsledujφcφ definice:
    bool next_permutation (BidirectionalIterator first,
          BidirectionalIterator last, [ Compare ] );
    bool prev_permutation (BidirectionalIterator first,
          BidirectionalIterator last, [ Compare ] );
    P°φklad 1 ukazuje permutace Φφsel. Druh² p°φklad pou₧φvß stejnou myÜlenku, s pou₧itφm ukazatel∙ na slova namφsto cel²ch Φφsel. V tomto p°φpad∞ je nutno poskytnout porovnßvacφ funkci, nebo¥ nechceme porovnßvat adresy ukazatel∙.
    bool nameCompare (char * a, char * b) { return strcmp(a, b) <= 0; }
    void permutation_example ()
    {
       // p°φklad 1, permutace hodnot 1 2 3
       int start [] = { 1, 2, 3};
       do
          copy (start, start + 3,
                ostream_iterator<int,char> (cout, " ")), cout << endl;
       while (next_permutation(start, start + 3));
       // p°φklad 2, permutace slov
       char * words = {"Alpha", "Beta", "Gamma"};
       do
          copy (words, words + 3,
             ostream_iterator<char *,char> (cout, " ")), cout << endl;
       while (next_permutation(words, words + 3, nameCompare));
       // p°φkladle 3, zp∞tnß permutace znak∙
       char * word = "bela";
       do
          cout << word << ' ';
       while (prev_permutation (word, &word[4]));
       cout << endl;
    }
    P°φklad 3 ukazuje pou₧itφ algoritmu reverznφch permutacφ, kter² generuje hodnoty v opaΦnΘm po°adφ. Tento p°φklad takΘ zaΦφnß uprost°ed sekvence mφsto od zaΦßtku. Zb²vajφcφ permutace slova ôbela,ö jsou beal, bale, bael, aleb, albe, aelb, aebl, able a koneΦn∞ abel.
    SluΦovßnφ p°ebφrß dv∞ °azenΘ sekvence a kombinuje je do jednΘ °azenΘ sekvence, proplΘtßnφm prvk∙ z ka₧dΘ kolekce podle pot°eby a generovßnφ novΘho seznamu. Algoritmus inplace_merge p°edpoklßdß sekvenci rozd∞lenou do dvou sousedφcφch sekcφ, z nich ka₧dß je se°azena. Spojovßnφ pak kombinuje tyto sekce do jednΘ a p°esouvß prvky podle pot°eby. Parametry musφ b²t obousm∞rnΘ iterßtory.
    void inplace_merge (BidirectionalIterator first,
       BidirectionalIterator middle,
       BidirectionalIterator last [, BinaryFunction ] );
    P°φklad ukazuje pou₧itφ algoritmu inplate_merge s vektorem a seznamem. Sekvence 0 2 4 6 8 1 3 5 7 9 je umφst∞na do vektoru. find pou₧ijeme k nalezenφ zaΦßtku lich²ch Φφsel v sekvenci. Dv∞ volßnφ inplace_merge,pak kombinujφ tyto dv∞ sekvence do jednΘ (pro vektor i seznam).
    void inplace_merge_example ()
    {
       // generovßnφ sekvence 0 2 4 6 8 1 3 5 7 9
       vector<int> numbers(10);
       for (int i = 0; i < 10; i++)
          numbers[i] = i < 5 ? 2 * i : 2 * (i - 5) + 1;
       // hledßnφ 1
       vector<int>::iterator midvec =
          find(numbers.begin(), numbers.end(), 1);
       // kopφrovßnφ do seznamu
       list<int> numList;
       copy (numbers.begin(), numbers.end(),
             inserter (numList, numList.begin()));
       list<int>::iterator midList =
             find(numList.begin(), numList.end, 1);
       // spojovßnφ seznam∙ do jednoho
       inplace_merge (numbers.begin(), midvec, numbers.end());
       inplace_merge (numList.begin(), midList, numList.end());
    }
    Algoritmus random_shuffle nßhodn∞ p°ehßzφ prvky v sekvenci. Je provedeno n p°ehozenφ, kdy₧ v sekvenci je n prvk∙. V²sledek je nep°edpov∞diteln². Proto₧e parametry musφ b²t iterßtory nßhodnΘho p°φstupu, tento algoritmus pracuje pouze s vektory, deque nebo normßlnφmi ukazateli. Nem∙₧e b²t pou₧φvßn se seznamy, mno₧inami a mapovßnφm.
    void random_shuffle (RandomAccessIterator first,
       RandomAccessIterator last [, Generator ] );
    Alternativnφ verze algoritmu pou₧φvß voliteln² t°etφ parametr. Tato hodnota musφ b²t generßtor nßhodn²ch Φφsel. Tento generßtor musφ p°ebφrat jako parametr kladnou hodnotu m a vracφ hodnotu mezi 0 a m-1. Jako u algoritmu generate tato funkce nßhodn²ch Φφsel m∙₧e b²t libovolnΘho typu objektu, kter² poskytuje operßtor volßnφ funkce.
    void random_shuffle_example ()
    {
       // vytvo°enφ vektoru 1 2 3 ... 10
       vector<int> numbers;
       generate(numbers.begin(), numbers.end(), iotaGen(1));
       // nßhodnΘ p°ehßzenφ prvk∙
       random_shuffle (numbers.begin(), numbers.end());
       // zopakovßnφ s poskytnutφm generßtoru nßhodn²ch Φφsel
       struct RandomInteger {
       {
          operator() (int m) { return rand() % m; }
       } random;
       random_shuffle (numbers.begin(), numbers.end(), random);
    }
  9. Nßsledujφcφ algoritmy odstra≥ujφ hodnoty ze sekvence. P°esouvajφ zb²vajφcφ hodnoty na zaΦßtek sekvence a vracejφ iterßtor urΦujφcφ, kde sekvence konΦφ. Hodnoty za iterßtorem mohou b²t zruÜeny (nap°. metodou erase). Podφvejme se na jednoduch² p°φklad. P°edpoklßdejme, ₧e chceme odstranit sudΘ prvky ze sekvence 1 2 3 4 5 6 7 8 9 10, a tedy pou₧ijeme algoritmus remove_if, kter² mßm dodß:

  10. 1 3 5 7 9 | 6 7 8 9 10
    Svislß Φßra reprezentuje pozici iterßtoru vrßcenΘho algoritmem remove_if. P∞t prvk∙ p°ed svislou Φarou reprezentuje po₧adovan² v²sledek a zb²vajφcφ jsou pouze p∙vodnφ hodnoty t∞chto mφst a m∙₧eme je tedy zruÜit.
    Oba zde popsanΘ algoritmy majφ i kopφrovacφ verzi. Kopφrovacφ verze zachovß nezm∞n∞n² originßl a v²sledek je umφst∞n do v²stupnφ sekvence.
    Algoritmus remove odstra≥uje ne₧ßdoucφ hodnoty ze sekvence. Stejn∞ jako u algoritmu find to mohou b²t hodnoty odpovφdajφcφ specifikovanΘ hodnot∞ nebo hodnoty vyhovujφcφ danΘmu tvrzenφ. Deklarace typ∙ parametr∙ je tato:
    ForwardIterator remove
       (ForwardIterator first, ForwardIterator last, const T &);
    ForwardIterator remove_if
       (ForwardIterator first, ForwardIterator last, Predicate);
    Algoritmus remove kopφruje hodnoty na zaΦßtek sekvence p°epsßnφm mφst odstra≥ovan²ch prvk∙. VÜechny neodstra≥ovanΘ prvky zachovßvajφ svΘ relativnφ po°adφ. Vrßcen² iterßtor urΦuje konec novΘ sekvence. Kopφrovacφ verze algoritmu kopφrujφ hodnoty do v²stupnφ sekvence, mφsto jejich transformace na mφst∞.
    OutputIterator remove_copy(InputIterator first,InputIterator last,
             OutputIterator result, const T &);
    OutputIterator remove_copy_if(InputIterator first,InputIterator last,
             OutputIterator result, Predicate);
    Pou₧itφ remove je ukßzßno v nßsledujφcφm programu.
    void remove_example ()
    {
       // vytvo°enφ seznamu Φφsel
       int data[] = {1, 2, 4, 3, 1, 4, 2};
       list<int> aList;
       copy (data, data+7, inserter(aList, aList.begin()));
       // odstran∞nφ 2, kopφrovßnφ do seznamu
       list<int> newList;
       remove_copy (aList.begin(), aList.end(),
          back_inserter(newList), 2);
       // odstran∞nφ 2 na mφst∞
       list<int>::iterator where;
       where = remove (aList.begin(), aList.end(), 2);
       aList.erase(where, aList.end());
       // odstran∞nφ vÜech sud²ch hodnot
       where = remove_if (aList.begin(), aList.end(), isEven);
       aList.erase(where, aList.end());
    }
    Algoritmus unique se p°esouvß po lineßrnφ sekvenci a eliminuje vÜechny neprvnφ v²skyty stejn²ch prvk∙. Parametry jsou popsßny dop°edn²mi iterßtory.
    ForwardIterator unique (ForwardIterator first,
       ForwardIterator last [, BinaryPredicate ] );
    Jak algoritmus prochßzφ kolekcφ, prvky jsou p°esouvßny na zaΦßtek sekvence, kde p°episujφ p∙vodnφ prvky. Jsou p°esunuty pouze unikßtnφ prvky, ostatnφ z∙stßvajφ nezm∞n∞ny. Nap°. sekvence jako je 1 3 3 2 2 2 4 bude zm∞n∞na na 1 3 2 4 | 2 2 4. Svislß Φßra indikuje vrßcenou hodnotu iterßtoru. Zb²vajφcφ prvky m∙₧eme zruÜit. Existuje takΘ kopφrujφcφ verze tohoto algoritmu.
    OutputIterator unique_copy(InputIterator first,InputIterator last,
           OutputIterator result [, BinaryPredicate ] );
    Tyto algoritmy jsou pou₧ity v jednoduchΘm programu.
    void unique_example ()
    {
       int data[] = {1, 3, 3, 2, 2, 4};
       list<int> aList;
       set<int> aSet;
       copy (data, data+6, inserter(aList, aList.begin()));
       // kopφrovßnφ unikßtnφch prvk∙ do mno₧iny
       unique_copy(aList.begin(),aList.end(),inserter(aSet,aSet.begin()));
       // unikßtnφ prvky na mφst∞
       list<int>::iterator where;
       where = unique(aList.begin(), aList.end());
       // odstran∞nφ zb²vajφcφch hodnot
       aList.erase(where, aList.end());
    }
  11. Nßsledujφcφ kategorie algoritm∙ jsou ty, kterΘ redukujφ celou sekvenci na jednu skalßrnφ hodnotu. Nezapome≥te, ₧e algoritmy accumulate a inner_product jsou deklarovßny v hlaviΦkovΘm souboru numeric.

  12. Algoritmy count a count_if jsou pou₧φvßny k zjiÜt∞nφ poΦtu prvk∙ odpovφdajφcφch danΘ hodnot∞ nebo spl≥ujφcφch danou podmφnku. Ka₧d² algoritmus je poskytnut ve dvou tvarech. Nov∞jÜφ tvar vracφ poΦet, zatφmco starÜφ tvar p°ebφrß odkaz na prom∞nou pro ulo₧enφ poΦtu jako parametr.
    Nov∞jÜφ tvar je souΦasn²m standardem. StarÜφ tvar je udr₧ovßn z d∙vodu zp∞tnΘ kompatibility a proto, ₧e nov² tvar m∙₧e mφt specißlnφ po₧adavky na p°ekladaΦ, kterΘ nemusφ b²t v₧dy spln∞ny.
    iterator_traits<InputIterator>::distance_type
    count (InputIterator first, InputIterator last, const T& value);
    iterator_traits<InputIterator>::distance_type
    count_if (InputIterator first, InputIterator last, Predicate pred);
    void count(InputIterator first,InputIterator last,const T&,Size &);
    void count_if(InputIterator first,InputIterator last,Predicate,Size &);
    Nßsledujφcφ k≤d ukazuje pou₧itφ starÜφch tvar∙ t∞chto algoritm∙. Volßnφm count zjistφme poΦet v²skyt∙ pφsmene e v °et∞zci a vyvolßnφm count_if poΦet samohlßsek.
    void count_example ()
    {
       int eCount = 0;
       int vowelCount = 0;
       char * text = "Now is the time to begin";
       count (text, text + strlen(text), 'e', eCount);
       count_if (text, text + strlen(text), isVowel, vowelCount);
       cout << "There are " << eCount << " letter e's " << endl
             << "and " << vowelCount << " vowels in the text:"
             << text << endl;
    }
    V²sledek generovan² algoritmem accumulate je hodnota vytvo°enß vlo₧enφm binßrnφho operßtoru mezi ka₧d² prvek sekvence a v²poΦtem v²sledku. Implicitnφ operßtor je operßtor sΦφtßnφ, lze jej ale nahradit libovolnou binßrnφ funkcφ. Musφ b²t poskytnuta poΦßteΦnφ hodnota. Tato hodnota je vrßcena prßzdnou sekvencφ a je p°epsßna lev²m operandem prvnφho v²poΦtu.
    ContainerType accumulate (InputIterator first, InputIterator last,
             ContainerType initial [, BinaryFunction ] );
    P°φklad ukazujφcφ pou₧itφ accumulate vytvß°φ souΦet a vektor celoΦφseln²ch hodnot. V prvnφm p°φklad∞ je poΦßteΦnφ hodnota 0 a je pou₧it implicitnφ operßtor (+). Dßle je pou₧ita poΦßteΦnφ hodnota 1 a Φtvrt²m parametrem je p°edßn operßtor nßsobenφ.
    void accumulate_example ()
    {
       int numbers[] = {1, 2, 3, 4, 5};
       // P°φklad 1, pouh² souΦet
       int sum = accumulate (numbers, numbers + 5, 0);
       int product = accumulate (numbers, numbers + 5, 1, times<int>());
       cout << "The sum of the first five integers is " << sum << endl;
       cout << "The product is " << product << endl;
       // P°φklad 2, s r∙zn²mi typy pro poΦßteΦnφ hodnotu
       list<int> nums;
       nums = accumulate (numbers, numbers+5, nums, intReplicate);
    }
    list<int>& intReplicate (list<int>& nums, int n)
    // p°idßnφ sekvence od n k 1 na konec seznamu
    {
       while (n) nums.push_back(n--);
       return nums;
    }
    PoΦßteΦnφ hodnota nebo v²sledek binßrnφ funkce nemusφ odpovφdat typu kontejneru. To je ukßzßno v p°φklad∞ 2 v²Üe. Zde jako poΦßteΦnφ hodnota je pou₧it prßzdn² seznam. Funkce p°ebφrß jako parametry seznam a celoΦφselnou hodnotu a opakovan∞ vklßdß hodnoty do seznamu. Vlo₧enΘ hodnoty tvo°φ klesajφcφ sekvenci od hodnoty parametru do 1. Pro nßÜ p°φklad bude v²sledn² seznam obsahovat nßsledujφcφ hodnoty: 1 2 1 3 2 1 4 3 2 1 5 4 3 2 1.
    P°edpoklßdejme, ₧e mßme dv∞ sekvence o n prvcφch: a1, a2, ... an a b1, b2, ... bn. Vnit°nφm produktem (skalßrnφm souΦinem) sekvencφ je souΦet souΦin∙ paralelnφch produkt∙, tj. hodnota a1 * b1 + a2 * b2 + ... + an * bn. Vnit°nφ produkty se vyskytujφ v °ad∞ v∞deckotechnick²ch v²poΦt∙. Nap°. vnit°nφ produkt °ßdek krßt sloupec je tradiΦnφm algoritmem nßsobenφ matic. Zobecn∞n² vnit°nφ produkt pou₧φvß stejnou strukturu, ale operace sΦφtßnφ a nßsobenφ mohou b²t nahrazeny jin²mi binßrnφmi funkcemi. Standardnφ knihovna obsahuje nßsledujφcφ algoritmus pro v²poΦet vnit°nφho produktu:
    ContainerType inner_product(InputIterator first1,InputIterator last1,
       InputIterator first2, ContainerType initialValue
       [ , BinaryFunction add, BinaryFunction times ] );
    Prvnφ t°i parametry definujφ dv∞ vstupnφ sekvence. Druhß sekvence je specifikovßna pouze poΦßteΦnφm iterßtorem a p°edpoklßdß se, ₧e mß alespo≥ tolik prvk∙ jako prvnφ sekvence. DalÜφm parametrem je poΦßteΦnφ hodnota pou₧itß pro operßtor sΦφtßnφ. Je to podobnΘ jako u algoritmu accumulate. V zobecn∞nΘm vnit°nφm produktu poslednφ dva parametry jsou binßrnφ funkce, kterΘ jsou pou₧ity mφsto operßtoru sΦφtßnφ a mφsto operßtoru nßsobenφ.
    V nßsledujφcφ p°φklad 2 ukazuje pou₧itφ alternativnφch funkcφ. Nßsobenφ je nahrazeno testem rovnosti a sΦφtßnφ je nahrazeno logick²m souΦtem. V²sledek je true, pouze pokud vÜechny dvojice si jsou rovny, jinak je false. Efekt je stejn² jako u algoritmu equal popsanΘm dßle.
    void inner_product_example ()
    {
       int a[] = {4, 3, -2};
       int b[] = {7, 3, 2};
       // p°φklad 1, jednoduch² vnit°nφ produkt
       int in1 = inner_product(a, a+3, b, 0);
       cout << "Inner product is " << in1 << endl;
       // p°φklad 2, u₧ivatelem definovanΘ operace
       bool anyequal = inner_product(a, a+3, b, true,
             logical_or<bool>(), equal_to<int>());
       cout << "any equal? " << anyequal << endl;
    }
    Algoritmus equal testuje dv∞ sekvence na pßrovou rovnost. Pou₧itφm alternativnφho binßrnφho tvrzenφ m∙₧e b²t takΘ pou₧it r∙znΘ testovßnφ paralelnφch sekvencφ. Parametry jsou jednoduchΘ vstupnφ iterßtory:
    bool equal (InputIterator first, InputIterator last,
             InputIterator first2 [, BinaryPredicate] );
    Algoritmus equal p°edpoklßdß, ale neov∞°uje, ₧e druhß sekvence mß alespo≥ tolik prvk∙ jako prvnφ. Je vrßceno true, pokud vÜechny hodnoty se shodujφ se sv²mi odpovφdajφcφmi prvky. Alternativnφ verze algoritmu p°edpoklßdß poskytnutφ logickΘ funkce pro test rovnosti. V p°φkladu je pou₧ita funkce greater_equal a je vrßceno true pouze tehdy, pokud vÜechny hodnoty prvnφ sekvence jsou v∞tÜφ nebo rovny ne₧ jim odpovφdajφcφ hodnoty v druhΘ sekvenci.
    void equal_example ()
    {
       int a[] = {4, 5, 3};
       int b[] = {4, 3, 3};
       int c[] = {4, 5, 3};
       cout << "a = b is: " << equal(a, a+3, b) << endl;
       cout << "a = c is: " << equal(a, a+3, c) << endl;
       cout << "a pair-wise greater-equal b is: "
          << equal(a, a+3, b, greater_equal<int>()) << endl;
    }
    Lexikßlnφ porovnßvßnφ dvou sekvencφ je slu₧ba se kterou se setkßme nap°. p°i °azenφ slov ve slovnφku. Kdy₧ porovnßvßme dv∞ slova, pak prvky (tj. znaky) dvou sekvencφ jsou porovnßvßny v pßrech tak dlouho, pokud se shodujφ. Nßsledujφcφ prvky pak urΦujφ vztah dvou sekvencφ (menÜφ prvek urΦuje menÜφ sekvenci). Pokud ob∞ sekvence se pln∞ shodujφ, pak si jsou rovny.
    Tuto ideu implementuje algoritmus lexicographical_compare. Algoritmus vracφ true, pokud prvnφ sekvence je menÜφ ne₧ druhß, jinak je vrßceno false. Algoritmus je zobecn∞n na libovolnΘ sekvence (pole, vektory, °et∞zce, seznamy a dalÜφ datovΘ struktury ze standardnφ knihovny).
    bool lexicographical_compare(InputIterator first1,InputIterator last1,
       InputIterator first2, InputIterator last2 [, BinaryFunction ] );
    Na rozdφl od v∞tÜiny algoritm∙ jsou zde ob∞ sekvence urΦeny dvojicemi iterßtor∙. Algoritmus m∙₧e takΘ p°ebφrat pßt² parametr, kter²m je binßrnφ funkce pou₧itß k porovnßvßnφ odpovφdajφcφch prvk∙ obou sekvencφ.
    P°φklad ukazuje pou₧itφ tohoto algoritmu se sekvencemi znak∙ a s poli celoΦφseln²ch hodnot.
    void lexicographical_compare_example()
    {
       char * wordOne = "everything";
       char * wordTwo = "everybody";
       cout << "compare everybody to everything " <<
          lexicographical_compare(wordTwo, wordTwo + strlen(wordTwo),
             wordOne, wordOne + strlen(wordOne)) << endl;
       int a[] = {3, 4, 5, 2};
       int b[] = {3, 4, 5};
       int c[] = {3, 5};
       cout << "compare a to b:" <<
          lexicographical_compare(a, a+4, b, b+3) << endl;
       cout << "compare a to c:" <<
          lexicographical_compare(a, a+4, c, c+2) << endl;
    }
  13. Dßle se budeme zab²vat algoritmy pou₧iteln²mi pro generovßnφ novΘ sekvence z existujφcφ sekvence provedenφm n∞jakΘho typu transformace. V²stupnφ sekvence je v∞tÜinou popsßna v²stupnφm operßtorem. Jako alternativa m∙₧e b²t takΘ pou₧it vklßdacφ iterßtor. Algoritmy partial_sum a adjacent_difference jsou deklarovßny v hlaviΦkovΘm souboru numeric.

  14. Algoritmus transform je pou₧iteln² k provedenφ obecnΘ transformace na jednΘ sekvenci nebo k vytvo°enφ novΘ sekvence aplikovßnφm binßrnφ funkce prvek po prvku na odpovφdajφcφ prvky ze dvou r∙zn²ch sekvencφ. Obecnß definice je tato:
    OutputIterator transform (InputIterator first, InputIterator last,
       OutputIterator result, UnaryFunction);
    OutputIterator transform (InputIterator first1, InputIterator last1,
       InputIterator first2,  OutputIterator result, BinaryFunction);
    Prvnφ tvar aplikuje unßrnφ funkci na ka₧d² prvek sekvence. V nßsledujφcφm programu je pou₧it k vytvo°enφ vektoru celoΦφseln²ch hodnot, kterΘ jsou aritmetickou negacφ hodnot ze seznamu. Vstupnφ a v²stupnφ iterßtor m∙₧e b²t stejn², pokud transformaci provßdφme na mφst∞, jak je takΘ ukßzßno v naÜem programu. Druh² tvar p°ebφrß dv∞ sekvence a aplikuje na n∞ binßrnφ funkci (v₧dy na dvojici odpovφdajφcφch si prvk∙ z obou sekvencφ). Transformace p°edpoklßdß, ₧e druhß sekvence mß alespo≥ tolik prvk∙ jako prvnφ. V²stup m∙₧e b²t uklßdßn do t°etφ sekvence nebo do n∞kterΘ ze dvou vstupnφch sekvencφ.
    int square(int n) { return n * n; }
    void transform_example ()
    {
       // generovßnφ seznamu hodnot od 1 do 6
       list<int> aList;
       generate_n (inserter(aList, aList.begin()), 6, iotaGen(1));
       // transformace prvk∙ umocn∞nφm, kopφrovßnφ do vektoru
       vector<int> aVec(6);
       transform (aList.begin(), aList.end(), aVec.begin(), square);
       // transformace vektoru na mφst∞, op∞t pou₧ita mocnina
       transform (aVec.begin(), aVec.end(), aVec.begin(), square);
       // paralelnφ transformace
       vector<int> cubes(6);
       transform (aVec.begin(), aVec.end(), aList.begin(),
          cubes.begin(), divides<int>());
    }
    ╚ßsteΦnΘ souΦty sekvence tvo°φ novou sekvenci, ve kterΘ ka₧d² prvek je urΦen souΦtem hodnot vÜech p°edchozφch prvk∙. Nap°. ΦßsteΦnΘ souΦty vektoru 1 3 2 4 5 tvo°φ nov² vektor 1 4 6 10 15. I kdy₧ k popisu operace je pou₧it termφn "souΦet", m∙₧e zde b²t pou₧ita libovolnß binßrnφ funkce.
    OutputIterator partial_sum (InputIterator first, InputIterator last,
           OutputIterator result [, BinaryFunction] );
    Pou₧itφm stejnΘ hodnoty pro oba vstupnφ iterßtory a v²sledek, ΦßsteΦnΘ souΦty mohou b²t zm∞n∞ny na transformaci na mφst∞.
    void partial_sum_example ()
    {
       // generovßnφ hodnot od 1 do 5
       vector<int> aVec(5);
       generate (aVec.begin(), aVec.end(), iotaGen(1));
       // v²stup ΦßsteΦn²ch souΦt∙
       partial_sum (aVec.begin(), aVec.end(),
          ostream_iterator<int> (cout, " ")), cout << endl;
       // v²stup ΦßsteΦn²ch souΦin∙
       partial_sum (aVec.begin(), aVec.end(),
          ostream_iterator<int> (cout, " "), times<int>() );
    }
    Sousednφ rozdφly sekvence tvo°φ novou sekvenci nßhradou ka₧dΘho prvku rozdφlem mezi prvkem je jeho bezprost°ednφm p°edch∙dcem. Prvnφ hodnota v novΘ sekvenci z∙stßvß nezm∞n∞nß. Nap°. sekvence (1, 3, 2, 4, 5) je transformovßna na (1, 3-1, 2-3, 4-2, 5-4) a dostaneme tedy sekvenci (1, 2, -1, 2, 1). V²raz "rozdφl" je mo₧no nahradit libovolnou binßrnφ funkcφ. Sousednφ souΦty nap°. pro tuto sekvenci mohou b²t (1, 4, 5, 6, 9).
    OutputIterator adjacent_difference (InputIterator first,
       InputIterator last, OutputIterator result [, BinaryFunction ]);
    Pomocφ stejnΘho iterßtoru na vstup i v²stup, dostaneme operaci provßd∞nou na mφst∞.
    void adjacent_difference_example ()
    {
       vector<int> aVec(5);
       generate (aVec.begin(), aVec.end(), iotaGen(1));
       // v²stup sousednφch rozdφl∙
       adjacent_difference (aVec.begin(), aVec.end(),
          ostream_iterator<int,char> (cout, " ")), cout << endl;
       // v²stup sousednφch souΦt∙
       adjacent_difference (aVec.begin(), aVec.end(),
          ostream_iterator<int,char> (cout, " "), plus<int>() );
    }
  15. Ve standardnφ knihovn∞ zb²vß jeÜt∞ n∞kolik algoritm∙. Algoritmus for_each p°ebφrß t°i parametry. Prvnφ dva jsou iterßtory popisujφcφ vyhodnocovanou sekvenci, t°etφ je unßrnφ funkce. Algoritmus aplikuje tuto funkci na ka₧dou hodnotu sekvence.

  16. function for_each(InputIterator first, InputIterator last, Function);
    Nap°. nßsledujφcφ ·sek k≤du pou₧φvß funkci print_if_leap, kterß vypisuje seznam p°estupn²ch let, kterΘ jsou mezi roky 1900 a 1997:
    cout << "leap years between 1990 and 1997 are: ";
    for_each (1990, 1997, print_if_leap);
    cout << endl;
    Je zajiÜt∞no, ₧e funkce p°edanß parametrem bude vyvolßna prßv∞ jednou pro ka₧d² prvek v sekvenci. Algoritmus for_each sßm vracφ hodnotu t°etφho parametru, i kdy₧ je obvykle ignorovßn.
    Nßsledujφcφ p°φklad prohledßvß pole celoΦφseln²ch hodnot reprezentujφcφch roky a urΦuje, kterΘ roky jsou p°estupnΘ:
    int vintageYears[] = {1947, 1955, 1960, 1967, 1994};
    ...
    cout << "vintage years which were also leap years are: ";
    for_each (vintageYears, vintageYears + 5, print_if_leap);
    cout << endl;
    VedlejÜφ efekty nejsou omezeny na v²pis. P°edpoklßdejme, ₧e mßme funkci countCaps, kterß poΦφtß v²skyty velk²ch pφsmen:
    int capCount = 0;
    void countCaps(char c)  { if (isupper(c)) capCount++; }
    Nßsledujφcφ p°φklad poΦφtß poΦet velk²ch pφsmen v °et∞zci:
    string advice = "Never Trust Anybody Over 30!";
    for_each(advice.begin(), advice.end(),countCaps);
    cout << "upper-case letter count is " << capCount << endl;
  17. Nynφ se zaΦneme zab²vat popisem obecn²ch algoritm∙ ze standardnφ knihovny, kterΘ jsou urΦenΘ pro °azenΘ kolekce. Jejich popis je uveden v nßsledujφcφ tabulce:

  18.  
    JmΘno Popis
    ╪adφcφ algoritmy
    sort ╪azenφ sekvence.
    stable_sort  ╪azenφ sekvence se zachovßnφm po°adφ ekvivalentnφch prvk∙.
    partial_sort ╪azenφ pouze Φßsti sekvence.
    partial_sort_copy ╚ßsteΦnΘ °azenφ s kopφrovßnφm.
    Hledßnφ n-tΘho nejv∞tÜφho prvku
    nth_element Lokalizace n-tΘho nejv∞tÜφho prvku.
    Binßrnφ hledßnφ
    binary_search Vyhledßvßnφ, nßvrat logickΘ hodnoty.
    lower_bound  Vyhledßvßnφ, nßvrat prvnφ pozice.
    upper_bound Vyhledßvßnφ, nßvrat poslednφ pozice.
    equal_range Vyhledßvßnφ, nßvrat obou pozic.
    SluΦovßnφ °azen²ch sekvencφ
    merge SlouΦenφ dvou se°azen²ch sekvencφ.
    Mno₧inovΘ operace
    set_union Sjednocenφ dvou mno₧in
    set_intersection Pr∙nik dvou mno₧in.
    set_difference Rozdφl dvou mno₧in.
    set_symmetric_difference Symetrick² rozdφl dvou mno₧in.
    includes ZjiÜt∞nφ, zda mno₧ina je podmno₧inou jinΘ mno₧iny.
    Operace s hromadou
    make_heap Zm∞na sekvence na hromadu.
    push_heap P°idßnφ novΘ hodnoty do hromady
    pop_heap Odstran∞nφ nejv∞tÜφ hodnoty z hromady
    sort_heap Zm∞na hromady na °azenou kolekci

    ╪azenΘ kolekce mohou b²t vytvß°eny pomocφ standardnφ knihovny r∙zn²mi zp∙soby. Nap°.

    V∞tÜina z t∞chto algoritm∙ existuje ve dvou verzφch. Prvnφ verze pou₧φvß operßtor < pro porovnßvßnφ prvk∙ kontejneru. Druhß, obecn∞jÜφ, pou₧φvß explicitnφ objekt porovnßvacφ funkce, kterou zapφÜeme jako Compare. Tento objekt funkce musφ b²t binßrnφ tvrzenφ. Jeliko₧ tento parametr je nepovinn², je uvßd∞n v hranat²ch zßvorkßch.
    Programy pou₧φvajφcφ tyto algoritmy, musφ vlo₧it hlaviΦkov² soubor algorithm:
    # include <algorithm>
  19. Jsou dva zßkladnφ °adφcφ algoritmy poskytnutΘ standardnφ knihovnou:

  20. void sort (RandomAccessIterator first,
          RandomAccessIterator last [, Compare ] );
    void stable_sort (RandomAccessIterator first,
          RandomAccessIterator last [, Compare ] );
    Algoritmus sort je nepatrn∞ rychlejÜφ, ale nezajiÜ¥uje, ₧e ekvivalentnφ prvky v p∙vodnφ sekvenci z∙stanou ve stejnΘm po°adφ ve v²slednΘ sekvenci (stabilnφ °azenφ). Pokud po°adφ je d∙le₧itΘ, pak pou₧ijeme verzi stable_sort. Proto₧e tyto algoritmy vy₧adujφ iterßtory nßhodnΘho p°φstupu, mohou b²t pou₧ity pouze s vektory, deque a normßlnφmi ukazateli C. Kontejner seznamu poskytuje takΘ svou vlastnφ metodu sort.
    M∙₧e b²t poskytnut porovnßvacφ operßtor, pokud operßtor < nevyhovuje. V nßsledujφcφ ukßzce je pou₧it k vytvo°enφ sestupnΘho namφsto vzestupnΘho po°adφ (alternativou je pou₧itφ reverznφch iterßtor∙).
    void sort_example ()
    {
       // napln∞nφ vector a deque nßhodn²mi Φφsly
       vector<int> aVec(15);
       deque<int> aDec(15);
       generate (aVec.begin(), aVec.end(), randomValue);
       generate (aDec.begin(), aDec.end(), randomValue);
       // vzestupnΘ °azenφ vektoru
       sort (aVec.begin(), aVec.end());
       // sestupnΘ °azanφ deque
       sort (aDec.begin(), aDec.end(), greater<int>() );
       // aternativnφ zp∙sob sestupnΘho °azenφ
       sort (aVec.rbegin(), aVec.rend());
    }
    Obecn² algoritmus partial_sort °adφ pouze Φßst sekvence. V prvnφ verzi algoritmu jsou pou₧ity t°i iterßtory popisujφcφ zaΦßtek, st°ed a konec sekvence. Pokud n je poΦet prvk∙ mezi poΦßtkem a st°edem, pak nejmenÜφch n prvk∙ bude p°esunuto do tohoto rozsahu. Zb²vajφcφ prvky jsou p°esunuty do druhΘ oblasti. Po°adφ prvk∙ v tΘto druhΘ oblasti je nedefinovanΘ.
    void partial_sort(RandomAccessIterator first,RandomAccessIterator middle,
       RandomAccessIterator last [ , Compare ]);
    Druhß verze algoritmu ponechßvß vstup nezm∞n∞n. V²stupnφ oblast je popsßna dvojicφ iterßtor∙ s nßhodn²m p°φstupem. Pokud n reprezentuje velikost tΘto oblasti, pak n nejmenÜφch prvk∙ je p°esunuto na v²stup v po°adφ. Pokud n je v∞tÜφ ne₧ vstup, pak cel² vstup je se°azen a umφst∞n na prvnφch n mφstech v²stupu. V obou p°φpadech konec v²stupnφ sekvence je vrßcen jako v²sledek operace.
    RandomAccessIterator partial_sort_copy(InputIterator first,
       InputIterator last, RandomAccessIterator result_first,
       RandomAccessIterator result_last [, Compare ] );
    Proto₧e vstup do tΘto verze algoritmu je specifikovßn pouze dvojicφ vstupnφch operßtor∙, algoritmus partial_sort_copy m∙₧e b²t pou₧it s libovoln²m kontejnerem ze standardnφ knihovny. V p°φkladu je pou₧it seznam.
    void partial_sort_example ()
    {
       // vytvo°enφ vektoru 15 cel²ch nßhodn²ch Φφsel
       vector<int> aVec(15);
       generate (aVec.begin(), aVec.end(), randomValue);
       // ΦßsteΦnΘ se°azenφ prvnφch sedmi pozic
       partial_sort (aVec.begin(), aVec.begin() + 7, aVec.end());
       // vytvo°enφ seznamu nßhodn²ch Φφsel
       list<int> aList(15, 0);
       generate (aList.begin(), aList.end(), randomValue);
       // se°azenφ pouze prvnφch sedmi prvk∙
       vector<int> start(7);
       partial_sort_copy (aList.begin(), aList.end(),
          start.begin(), start.end(), greater<int>());
    }
  21. P°edpoklßdejme, ₧e mßme sekvenci 2 5 3 4 7 a pot°ebujeme zjistit prost°ednφ prvek (medißn). M∙₧eme to provΘst funkcφ nth_element. Jeden v²sledek m∙₧e b²t nßsledujφcφ sekvence:

  22. 3 2 | 4 | 7 5
    SvislΘ Φßry rozd∞lujφ v²sledek na t°i Φßsti; prvky, p°ed po₧adovanou hodnotou, po₧adovanß hodnota a prvky za po₧adovanou hodnotou. PovÜimn∞te si, ₧e hodnoty v prvnφ a t°etφ Φßsti jsou nese°azenΘ. Je pouze po₧adovßno, aby hodnoty v prvnφ Φßsti byly menÜφ a ve t°etφ Φßsti byly v∞tÜφ ne₧ po₧adovanß hodnota.
    T°i iterßtory poskytnutΘ jako parametry algoritmu nth_element rozd∞lujφ sekvenci jak je popsßno. Je Φßst p°ed iterßtorem nth, jedna hodnota urΦenß nth a Φßst za iterßtorem nth. Prvnφ a t°etφ Φßst mohou b²t prßzdnΘ.
    void nth_element(RandomAccessIterator first,RandomAccessIterator nth,
       RandomAccessIterator last [, Compare ] );
    Nßsledujφcφ program ukazuje nalezenφ pßtΘ nejv∞tÜφ hodnoty z vektoru nßhodn²ch Φφsel.
    void nth_element_example ()
    {
       vector<int> aVec(10);
       generate (aVec.begin(), aVec.end(), randomValue);
       vector<int>::iterator nth = aVec.begin() + 4;
       nth_element (aVec.begin(), nth, aVec.end());
       cout << "fifth largest is " << *nth << endl;
    }
  23. Standardnφ knihovna poskytuje n∞kolik r∙zn²ch variant algoritmu binßrnφho vyhledßvßnφ. VÜechny provßd∞jφ pouze p°ibli₧n∞ log n porovnßvßnφ, kde n je poΦet prvk∙ v rozsahu popsanΘm parametry. Algoritmus pracuje dob°e s iterßtory nßhodnΘho p°φstupu, kterΘ poskytuje vektor nebo deque. Pracuje takΘ s iterßtory nenßhodnΘho p°φstupu, kterΘ jsou generovanΘ seznamy (v tomto p°φpad∞ je pou₧ito lineßrnφ vyhledßvßnφ). Binßrnφ vyhledßvßnφ nenφ nutno provßd∞t na mno₧inßch nebo multiset, nebo¥ tyto t°φdy kontejner∙ poskytujφ vlastnφ vyhledßvacφ algoritmy, kterΘ jsou mnohem efektivn∞jÜφ.

  24. Obecn² algoritmus binary_search vracφ true, pokud sekvence obsahuje hodnotu, kterß je ekvivalentem parametru. Zopakujme si, ₧e ekvivalentnφ znamenß ₧e Compare(value, arg) i Compare(arg, value) jsou false.
    bool binary_search (ForwardIterator first, ForwardIterator last,
          const T & value [, Compare ] );
    V ostatnφch situacφch je d∙le₧itΘ znßt pozici hledanΘ hodnoty. Tyto informace jsou vraceny t∞mito algoritmy:
    ForwardIterator lower_bound (ForwardIterator first,
          ForwardIterator last, const T& value [ , Compare ] );
    ForwardIterator upper_bound (ForwardIterator first,
          ForwardIterator last, const T& value [, Compare ] );
    pair<ForwardIterator,ForwardIterator> equal_range(ForwardIterator first,
          ForwardIterator last, const T& value [, Compare ] );
    Algoritmus lover_bound vracφ iterßtor urΦujφcφ prvnφ pozici, na kterou by parametr mohl b²t vlo₧en bez poruÜenφ po°adφ, zatφmco upper_bound vracφ poslednφ tuto pozici. Oba jsou provßd∞ny spoleΦn∞ v algoritmu equal_range, kter² vracφ pßr iterßtor∙.
    NßÜ p°φklad ukazuje tyto funkce pou₧itΘ s vektorem nßhodn²ch cel²ch Φφsel.
    void binary_search_example ()
    {
       // vytvo°enφ se°azenΘho vektoru 15 nßhodn²ch Φφsel
       vector<int> aVec(15);
       generate (aVec.begin(), aVec.end(), randomValue);
       sort (aVec.begin(), aVec.end());
       // zjiÜt∞nφ zda kontejner obsahuje 11
       if (binary_search (aVec.begin(), aVec.end(), 11))
          cout << "contains an 11" << endl;
       else
          cout << "does not contain an 11" << endl;
       // vlo₧enφ 11 a 14
       vector<int>::iterator where;
       where = lower_bound (aVec.begin(), aVec.end(), 11);
       aVec.insert (where, 11);
       where = upper_bound (aVec.begin(), aVec.end(), 14);
       aVec.insert (where, 14);

    }

  25. Algoritmus merge kombinuje dv∞ se°azenΘ sekvence do tvaru novΘ se°azenΘ sekvence. Velikost v²sledku je souΦet velikostφ p°edan²ch sekvencφ. To je v kontrastu s operacφ set_union, kterß eliminuje prvky, kterΘ jsou opakovan∞ v obou mno₧inßch. Dv∞ sekvence jsou popsßny dvojicφ iterßtor∙, zatφmco v²sledek jednφm v²stupnφm iterßtorem.

  26. OutputIterator merge (InputIterator first1, InputIterator last1,
       InputIterator first2, InputIterator last2,
       OutputIterator result [, Compare ]);
    P°φklad ukazuje jednoduchΘ sluΦovßnφ, pou₧itφ sluΦovßnφ s vklßdßnφm a pou₧itφ sluΦovßnφ s iterßtorem v²stupnφho proudu.
    void merge_example ()
    {
       // vytvo°enφ seznamu a vektoru 10 nßhodn²ch Φφsel
       vector<int> aVec(10);
       list<int> aList(10, 0);
       generate (aVec.begin(), aVec.end(), randomValue);
       sort (aVec.begin(), aVec.end());
       generate_n (aList.begin(), 10, randomValue);
       aList.sort();
       // slouΦenφ do vektoru
       vector<int> vResult (aVec.size() + aList.size());
       merge (aVec.begin(), aVec.end(), aList.begin(), aList.end(),
          vResult.begin());
       // slouΦenφ do seznamu
       list<int> lResult;
       merge (aVec.begin(), aVec.end(), aList.begin(), aList.end(),
          inserter(lResult, lResult.begin()));
       // slouΦenφ na v²stup
       merge (aVec.begin(), aVec.end(), aList.begin(), aList.end(),
          ostream_iterator<int,char> (cout, " "));
       cout << endl;
    }
  27. S mno₧inov²mi operacemi pro t°φdu set jsme se ji₧ seznßmili. Algoritmy implementujφcφ tyto operace jsou obecnΘ a aplikovatelnΘ na libovolnΘ °azenΘ datovΘ struktury. Algoritmy p°edpoklßdajφ, ₧e vstupnφ rozsahy jsou °azenΘ kolekce, kterΘ reprezentujφ multiset; tj. prvky se mohou opakovat. Pokud vstupy jsou reprezentovanΘ mno₧inami, pak v²stup bude takΘ mno₧ina.

  28. Mno₧inovΘ operace majφ stejn² formßt. Dv∞ vstupnφ mno₧iny jsou specifikovßny dvojicemi vstupnφch iterßtor∙. V²stupnφ mno₧ina je specifikovßna iterßtorem a konec tohoto rozsahu je vrßcen jako nßvratovß hodnota. Jako poslednφ parametr m∙₧e b²t poskytnuta porovnßvacφ funkce.
    OutputIterator set_union(InputIterator first1,InputIterator last1,
       InputIterator first2, InputIterator last2,
       OutputIterator result [, Compare ] );
    P°φklad ukazuje pou₧itφ Φty° mno₧inov²ch algoritm∙: set_union, set_intersection, set_difference a set_symmetric_difference. Je zde takΘ pou₧ito volßnφ merge. Algoritmus includes se nepatrn∞ liÜφ. Op∞t dv∞ vstupnφ mno₧iny jsou specifikovanΘ pßry vstupnφch iterßtor∙ a porovnßvacφ operßtor jako pßt² voliteln² parametr. Nßvratovß hodnota je true, pokud prvnφ mno₧ina je celß obsa₧ena ve druhΘ a v opaΦnΘm p°φpad∞ je vrßceno false.
    void set_example ()
    {
       ostream_iterator<int> intOut (cout, " ");
       // vytvo°enφ dvou °azen²ch seznam∙
       list<int> listOne, listTwo;
       generate_n (inserter(listOne, listOne.begin()), 5, iotaGen(1));
       generate_n (inserter(listTwo, listTwo.begin()), 5, iotaGen(3));
       // sjednocenφ
       set_union (listOne.begin(), listOne.end(),
          listTwo.begin(), listTwo.end(), intOut), cout << endl;
       // sluΦovßnφ
       merge (listOne.begin(), listOne.end(),
          listTwo.begin(), listTwo.end(), intOut), cout << endl;
       // pr∙nik
       set_intersection (listOne.begin(), listOne.end(),
          listTwo.begin(), listTwo.end(), intOut), cout << endl;
       // rozdφl
       set_difference (listOne.begin(), listOne.end(),
          listTwo.begin(), listTwo.end(), intOut), cout << endl;
       // symetrick² rozdφl
       set_symmetric_difference (listOne.begin(), listOne.end(),
          listTwo.begin(), listTwo.end(), intOut), cout << endl;
       if (includes (listOne.begin(), listOne.end(),
          listTwo.begin(), listTwo.end()))
             cout << "set is subset" << endl;
       else
          cout << "set is not subset" << endl;
    }
    Hromada je binßrnφ strom, ve kterΘm ka₧d² uzel je v∞tÜφ ne₧ hodnoty p°i°azenΘ k jeho potomk∙m. Hromada m∙₧e b²t velmi efektivn∞ ulo₧ena ve vektoru, umφst∞nφm pod°φzen²ch uzl∙ uzlu i na pozice 2 * i + 1 a 2 * i + 2.
    Pomocφ tohoto k≤dovßnφ, nejv∞tÜφ hodnota v hromad∞ je v₧dy umφst∞na na poΦßteΦnφ pozici a m∙₧e b²t tedy velmi efektivn∞ zφskßna. Dßle existujφ efektivnφ algoritmy pro p°idßvßnφ novΘho prvku a odstra≥ovßnφ nejv∞tÜφho prvku z hromady. Z t∞chto d∙vod∙ je hromada p°irozenou reprezentacφ pro datov² typ priority_queue.
    Algoritmus make_heap p°ebφrß rozsah specifikovan² iterßtory nßhodnΘho p°φstupu a p°evßdφ jej na hromadu. PoΦet po₧adovan²ch krok∙ je lineßrnφ funkcφ poΦtu prvk∙ rozsahu.
    void make_heap (RandomAccessIterator first,
          RandomAccessIterator last [, Compare ]);
    Nov² prvek je p°idßvßn na hromadu vlo₧enφm na konec rozsahu (nap°. pou₧itφm metody push_back), nßsledovan²m vyvolßnφm algoritmu push_heap. Tento algoritmus obnovφ vlastnosti hromady.
    void push_heap (RandomAccessIterator first,
          RandomAccessIterator last [, Compare ]);
    Algoritmus pop_heap p°ehazuje prvnφ a poslednφ prvek v rozsahu, a potom obnovuje kolekci bez poslednφho prvku. Nejv∞tÜφ hodnota p∙vodnφ kolekce je tedy dostupnß jako poslednφ prvek v rozsahu, zatφmco zbytek kolekce pokraΦuje v zφskßvßnφ vlastnostφ hromady.
    void pop_heap (RandomAccessIterator first,
          RandomAccessIterator last [, Compare ]);
    Algoritmus sort_heap p°evßdφ hromadu na °azenou kolekci. Algoritmus nenφ stabilnφ.
    void sort_heap (RandomAccessIterator first,
          RandomAccessIterator last [, Compare ]);
    Nßsleduje p°φklad programu s pou₧itφm t∞chto funkcφ:
    void heap_example ()
    {
       // vytvo°enφ hromady 15 nßhodn²ch Φφsel
       vector<int> aVec(15);
       generate (aVec.begin(), aVec.end(), randomValue);
       make_heap (aVec.begin(), aVec.end());
       cout << "Largest value " << aVec.front() << endl;
       // odstran∞nφ nejv∞tÜφho prvku
       pop_heap (aVec.begin(), aVec.end());
       aVec.pop_back();
       // p°idßnφ 97 k hromad∞
       aVec.push_back (97);
       push_heap (aVec.begin(), aVec.end());
       // p°evedenφ do °azenΘ kolekce
       sort_heap (aVec.begin(), aVec.end());
    }
  29. Rozhranφ standardnφch alokßtor∙ zaobaluje typy a funkce pot°ebnΘ ke sprßv∞ uklßdßnφ dat obecn²m zp∙sobem. Rozhranφ poskytuje:
  30. Rozhranφ alokßtoru dßvß mechanismus pro sprßvu uklßdßnφ dat a odd∞luje tento mechanismus od t°φd a funkcφ pou₧it²ch k ·dr₧b∞ asociacφ mezi datov²mi prvky. Toto eliminuje p°episovßnφ kontejner∙ a algoritm∙ p°i pou₧itφ jinΘho uklßdacφho mechanismu. Rozhranφ zaobaluje vÜechny uklßdacφ mechanismy v alokßtoru a poskytuje tento alokßtor k existujφcφmu kontejneru, kdy₧ je pot°eba.
    Standardnφ knihovna poskytuje implicitnφ t°φdu alokßtoru, alokßtor, kter² implementuje toto rozhranφ pomocφ operßtor∙ new a delete pro vÜechnu sprßvu uklßdßnφ.
    Pou₧φvßnφ alokßtor∙ s existujφcφ standardnφ knihovnou t°φd kontejner∙ je jednoduch² proces. Pouze poskytneme typ alokßtoru p°i vytvß°enφ kontejneru a poskytneme aktußlnφ objekt alokßtoru kdy₧ vytvß°φme objekt kontejneru:
    my_allocator alloc<int>;  // vytvo°enφ alokßtoru
    vector<int,my_allocator<int> > v(alloc);  // Pou₧itφ alokßtoru
    VÜechny standardnφ kontejnery majφ implicitnφ parametr Üablony alokßtoru typu allocator<T> a objekt Allocator, kde Allocator je parametr konstruktoru. To znamenß, ₧e nejjednoduÜÜφ pou₧itφ alokßtor∙ je jejich celkovΘ ignorovßnφ. Kdy₧ nespecifikujeme alokßtor, pak je pou₧it implicitnφ alokßtor.
    Pokud poskytneme jin² typ alokßtoru jako parametr Üablony, pak typ objektu, kter² poskytneme, musφ odpovφdat typu Üablony. Nap°. nßsledujφcφ k≤d zp∙sobφ chybu p°ekladu, proto₧e typy v Üablon∞ a volßnφ konstruktoru alokßtoru se neshodujφ:
    template <class T> class my_alloc;
    list <int, allocator<int> > my_list(my_alloc()); // Chyba!
    Nßsledujφcφ volßnφ konstruktoru alokßtoru je ji₧ sprßvnΘ:
    list <int, my_alloc<int> > my_list(my_alloc());
  31. Definovßnφ naÜich vlastnφch alokßtor∙ je relativn∞ jednoduch² proces. Standardnφ knihovna obsahuje jistΘ rozhranφ obsahujφcφ typy a funkce. Alokßtor, kter² vytvß°φme musφ syntakticky vyhovovat t∞mto metodßm a typ∙m. Standardnφ knihovna takΘ specifikuje Φßst sΘmantiky pro typ alokßtoru.

  32. Alokßror vyhovujφcφ specifikaci alokßtoru standardnφ knihovny musφ mφt nßsledujφcφ rozhranφ. V p°φkladu nahradφme my_allocator sv²m vlastnφm jmΘnem alokßtoru:
    template <class T>
    class my_allocator
    {
      typedef implementation_defined size_type;
      typedef implementation_defined difference_type
      typedef implementation_defined pointer;
      typedef implementation_defined const_pointer;
      typedef implementation_defined reference;
      typedef implementation_defined const_reference;
      typedef implementation_defined value_type;

      template <class U>
      struct rebind { typedef allocator<U> other; };
    Ka₧d² typ ukazatele v tomto rozhranφ musφ mφt konverzi na void*. Musφ b²t mo₧no pou₧φt v²sledek void* jako hodnotu this v konstruktoru a destruktoru a v p°evodech na B<void>::pointer (pro p°φsluÜnΘ B) pro pou₧itφ v B::deallocate().
    Metoda rebind umo₧≥uje kontejneru vytvß°et alokßtor pro n∞kterΘ typy poskytnutΘ jako parametr Üablony. Nap°. kontejner seznamu zφskßvß implicitn∞ allocator<T>, ale seznam takΘ pot°ebuje alokovat list_nodes. Kontejner m∙₧e vytvo°it alokßtor pro list_nodes mimo alokßtor pro T takto:
    Allocator::rebind<list_node>::other list_node_allocator;
    Nßsleduje popis metod, kterΘ alokßtor standardnφ knihovny musφ poskytovat:
    my_allocator();
    template <class U>
    my_allocator(const my_allocator<U>&);
    template <class U>
    operator=(const my_allocator<U>&);
    ~my_allocator();
        Konstruktory a destruktor.
    pointer address(reference r) const;
        Vracφ adresu r jako typ pointer. Tato a nßsledujφcφ funkce jsou pou₧ity pro p°evod odkaz∙ na ukazatele.
    const_pointer address(const_reference r) const;
        Vracφ adresu r jako typ const_pointer.
    pointer allocate(size_type n);
        Alokuje mφsto pro n hodnot T.
    template <class T, class U>
    types<T>::pointer allocate(size_type n,
        typename my_allocator<void>::const_pointer hint = 0);
        Alokuje mφsto pro hint hodnot T.
    void deallocate(pointer);
        Dealokace mφsta zφskanΘho volßnφm allocate.
    size_type max_size();
        Vracφ nejv∞tÜφ mo₧nΘ mφsto dostupnΘ pro volßnφ allocate.
    void construct(pointer p, const T& val);
        Vytvß°φ objekt typu T na mφst∞ p. Efekt je: new((void*)p) T(u);
    void destroy(pointer p);
        Volß destruktor na hodnotu urΦenou p. Efekt je: ((T*)p)->~T()
    Nßsleduje popis funkcφ (ne metod), kterΘ alokßtor standardnφ knihovny musφ poskytnout:
    template <class T>
    my_allocator::pointer
    operator new(my_allocator::size_type, my_allocator&);
        Alokuje mφsto pro jeden objekt typu T pomocφ my_allocator::allocate. Efekt je: new((void*)x.template allocate<T>(1)) T;
    template <class T, class U>
    bool operator==(const my_allocator<T>& a, const my_allocator<U>& b);
        Vracφ true, pokud alokßtory b a a mohou b²t ·sp∞Ün∞ zam∞n∞ny (tj. b m∙₧e b²t pou₧it k dealokaci a a naopak).
    template <class T, class U>
    bool operator!=(const my_allocator<T>& a, const my_allocator<U>& b);
        Vracφ !(a == b).
    Rogue Wave poskytuje alternativnφ rozhranφ alokßtoru pro ty p°ekladaΦe, kterΘ nepodporujφ Üablony t°φd a Üablony metod. Tφm se ale zab²vat nebudeme.

  33. Standardnφ knihovna poskytuje mno₧inu t°φd pro oznamovßnφ chyb. Tyto t°φdy pou₧φvajφ slu₧by zpracovßnφ v²jimek. Knihovna implementuje jist² model chyb, ve kterΘm chyby d∞lφme do dvou kategoriφ: na logickΘ a b∞hovΘ chyby.

  34. LogickΘ chyby jsou chyby zp∙sobenΘ problΘmy v internφ logice programu. Je mo₧no jim zabrßnit. B∞hovΘ chyby jsou chyby, kterΘ nejsou p°edvφdatelnΘ. Jednß se o chyby generovanΘ mimo °φzenφ programu, jako jsou chyby periferiφ.
    P°i zpracovßnφ v²jimek v naÜem programu musφme vlo₧it hlaviΦkov² soubor stdexcept:
    #include <stdexcept>
    Hierarchie d∞diΦnosti t∞chto t°φd je tato:
    exception
        logic_error
          domain_error
          invalid_argument
          length_error
          out_of_range
       runtime_error
          range_error
          overflow_error
          underflow_error
    T°φdy logic_error a runtime_error jsou odvozeny od t°φdy exception. VÜechny ostatnφ t°φdy v²jimek jsou odvozeny od logic_error nebo od runtime_error.
    VÜechny v²jimky generovanΘ n∞jak²m prvkem knihovny jsou souΦßstφ standardnφ hierarchie v²jimek. Z odkazu na tuto t°φdu urΦφme, kterß funkce generovala v²jimku. Jistou v²jimku pak m∙₧eme zachytit. Nap°. pokud volßme funkci insert na °et∞zec s pozicφ, kterß je z n∞jakΘho d∙vodu nedovolenß.
    string s;
    int n;
    ...
    try
    {
      s.insert(n,"Howdy");
    }
    catch (const exception& e)
    {
       // prßce s v²jimkou
    }
    Ke generovßnφ naÜich vlastnφch v²jimek, jednoduÜe vytvo°φme v²jimku p°φsluÜnΘho typu, p°i°adφme ji p°φsluÜnou zprßvu a nechßme ji Üφ°it. Nap°.
    ...
    if (n > max)
       throw out_of_range("Your past the end, bud");
    T°φda exception slou₧φ jako zßkladnφ t°φda pro vÜechny ostatnφ t°φdy v²jimek. Definuje standardnφ rozhranφ. Toto rozhranφ zahrnuje metodu what, kterß vracφ nulou ukonΦen² °et∞zec reprezentujφcφ zprßvu v²jimky. Tato funkce se obvykle pou₧φvß v klazuli catch, jak je ukßzßno v demonstraΦnφm p°φklad∞.
    T°φda exception neobsahuje konstruktor p°ebφrajφcφ °et∞zec zprßvy, ale vÜechny t°φdy odvozenΘ od exception tento konstruktor musφ poskytnout.
    Zßkladem pro generovßnφ v²jimky je pou₧itφ nßsledujφcφho k≤du:
    throw exception;
    Toto obecn∞ nenφ p°φliÜ u₧iteΦnΘ, nebo¥ p°i zachycenφ tΘto v²jimky nenφ mo₧no zjistit typ vzniklΘ chyby. Mφsto zßkladu v²jimek obvykle pou₧φvßme odvozenou t°φdu. Hierarchii t°φd v²jimek m∙₧eme rozÜφ°it odvozenφm svΘ vlastnφ t°φdy. To umo₧≥uje oznamovat chyby specifickΘ pro nßÜ problΘm. Nap°.
    class bad_packet_error : public runtime_error
    {
       public:
          bad_packet_error(const string& what);
    };
    if (bad_packet())
       throw bad_packet_error("Packet size incorrect");
    Nßsledujφcφ program ukazuje pou₧itφ v²jimek (cel² program je ulo₧en v exceptn.cpp).
    #include <stdexcept>
    #include <string>
    static void f() { throw runtime_error("a runtime error"); }
    int main ()
    {
      string s;
      try
      {
        s.replace(100,1,1,'c');
      }
      catch (const exception& e)
      {
        cout << "Got an exception: " << e.what() << endl;
      }
      try
      {
        f();
      }
      catch (const exception& e)
      {
        cout << "Got an exception: " << e.what() << endl;
      }
     return 0;
    }
  35. T°φda auto_prt zaobaluje libovoln² ukazatel zφskan² pomocφ new a poskytuje automatickΘ zruÜenφ tohoto ukazatele. Ukazatel zaobalen² objektem auto_ptr je zruÜen, kdy₧ sßm auto_ptr je uvoln∞n. Pro p°φstup k tΘto t°φd∞ je nutno vlo₧it hlaviΦkov² soubor memory:

  36. #include <memory>
    Objekt auto_ptr vytvo°φme n∞kter²m konstruktorem auto_ptr, p°i°azenφm jednoho objektu auto_ptr jinΘmu nebo pou₧itφm metody reset. Pouze jeden auto_ptr vlastnφ konkrΘtnφ ukazatel v jist² okam₧ik (v²jimku tvo°φ ukazatel NULL). Pou₧itφm kopφrovacφho konstruktoru nebo operßtoru p°i°azenφ p°edßme vlastnictvφ na jin² objekt auto_ptr. Nap°. p°edpoklßdejme, ₧e auto_ptr vytvo°φme takto:
    auto_ptr<string> a(new string);
    Objekt auto_ptr jmΘna a nynφ vlastnφ nov∞ vytvo°en² ukazatel. Kdy₧ a je uvoln∞no (nap°. kdy₧ se dostane mimo rozsah), pak ukazatel bude zruÜen. Ale, pokud p°i°adφme a objektu b, pomocφ p°i°azovacφho operßtoru:
    auto_ptr<string> b = a;
    pak ukazatel vlastnφ b. Pokud se nynφ a dostane mimo rozsah, pak ukazatel nebude ovlivn∞n. Bude zruÜen, kdy₧ se mimo rozsah dostane b. Objekt auto_ptr p°ebφrß odpov∞dnost za svΘ zruÜenφ.
    Pro p°φstup k ukazateli dr₧enΘmu auto_ptr pou₧ijeme operator*, operator-> nebo funkci get. Nap°. nßsledujφcφ t°i p°φkazy m∙₧eme pou₧φt pro p°i°azenφ "What's up Doc" do °et∞zce nynφ odkazovanΘho objektem b.
    *b = "What's up Doc";
    *(b.get()) = "What's up Doc";
    b->assign("What's up Doc");
    auto_ptr takΘ poskytuje metodu release, kterß uvol≥uje vlastnictvφ ukazatele. Libovoln² auto_ptr, kter² nevlastnφ specifick² ukazatel, ukazuje na NULL, tedy volßnφ release nastavuje auto_ptr na NULL. V p°edchozφm p°φklad∞, kde a je p°i°azeno b je dr₧en² ukazatel uvoln∞n a nastaven na NULL.
    Nßsledujφcφ program ukazuje pou₧itφ auto_ptr k zajiÜt∞nφ, ₧e ukazatele dr₧enΘ ve vektoru jsou p°i odstran∞nφ zruÜeny. Cel² program nalezneme v souboru autoptr.cpp.
    #include <vector>
    #include <memory>
    #include <string>
    int main()
    {
      {
        // prvnφ chybn² zp∙sob
        vector<string*> v;
        v.insert(v.begin(), new string("Florence"));
        v.insert(v.begin(), new string("Milan"));
        v.insert(v.begin(), new string("Venice"));
        // nynφ odstranφme prvnφ prvek
        v.erase(v.begin());
        // °et∞zec("Venice") je odstran∞n, ale nenφ zruÜen
      }
      {
        // nynφ sprßvn² zp∙sob
        vector<auto_ptr<string> > v;
        v.insert(v.begin(), auto_ptr<string>(new string("Florence")));
        v.insert(v.begin(), auto_ptr<string>(new string("Milan")));
        v.insert(v.begin(), auto_ptr<string>(new string("Venice")));
        // nynφ odstranφme prvnφ prvek
        v.erase(v.begin());
        // vÜe v po°ßdku
      }
      return 0;
    }
31. Knihovna standardnφch Üablon III