|
||||
|
ÀÄÀÏÒÅÐÛÀäàïòåðû - øàáëîííûå êëàññû, êîòîðûå îáåñïå÷èâàþò îòîáðàæåíèÿ èíòåðôåéñà. Íàïðèìåð, insert_iterator îáåñïå÷èâàåò êîíòåéíåð èíòåðôåéñîì èòåðàòîðà âûâîäà. Àäàïòåðû êîíòåéíåðîâ (Container adaptors)×àñòî áûâàåò ïîëåçíî îáåñïå÷èòü îãðàíè÷åííûå èíòåðôåéñû êîíòåéíåðîâ. Áèáëèîòåêà ïðåäîñòàâëÿåò stack, queue è priority_queue ÷åðåç àäàïòåðû, êîòîðûå ìîãóò ðàáîòàòü ñ ðàçëè÷íûìè òèïàìè ïîñëåäîâàòåëüíîñòåé. Ñòåê (Stack)Ëþáàÿ ïîñëåäîâàòåëüíîñòü, ïîääåðæèâàþùàÿ îïåðàöèè back, push_back è pop_back, ìîæåò èñïîëüçîâàòüñÿ äëÿ ìîäèôèêàöèè stack.  ÷àñòíîñòè, ìîãóò èñïîëüçîâàòüñÿ vector, list è deque. template ‹class Container› class stack { friend bool operator==(const stack‹Container›& õ, const stack‹Container›& y); friend bool operator‹(const stack‹Container›& õ, const stack‹Container›& y); public: typedef Container::value_type value_type; typedef Container::size_type size_type; protected: Container c; public: bool empty() const {return c.empty();} size_type size() const {return c.size();} value_type& top() {return c.back();} const value_type& top() const {return c.back();} void push(const value_type& õ) {ñ.push_back(õ);} void pop() {c.pop_back();} }; template ‹class Container› bool operator==(const stack ‹Container›& õ, const stack‹Container›& y) {return õ.ñ == ó.ñ;} template ‹class Container› bool operator‹(const stack‹Container›& õ, const stack‹Container›& y) {return õ.ñ ‹ ó.ñ;} Íàïðèìåð, stack‹vector‹int› › - öåëî÷èñëåííûé ñòåê, ñäåëàííûé èç vector, à stack‹deque‹char› › - ñèìâîëüíûé ñòåê, ñäåëàííûé èç deque. Î÷åðåäü (Queue)Ëþáàÿ ïîñëåäîâàòåëüíîñòü, ïîääåðæèâàþùàÿ îïåðàöèè front, push_back è pop_front, ìîæåò èñïîëüçîâàòüñÿ äëÿ ìîäèôèêàöèè queue.  ÷àñòíîñòè, ìîãóò èñïîëüçîâàòüñÿ list è deque. template ‹class Container› class queue { friend bool operator==(const queue‹Container›& õ, const queue‹Container›& y); friend bool operator‹(const queue‹Container›& õ, const queue‹Container›& y); public: typedef Container::value_type value_type; typedef Container::size_type size_type; protected: Container c; public: bool empty() const {return c.empty();} size_type size() const {return c.size();} value_type& front() {return c.front();} const value_type& front() const {return c.front();} value_type& back() {return c.back();} const value_type& back() const {return c.back();} void push(const value_type& õ) {ñ.push_back(õ);} void pop() {ñ.pop_front();} }; template ‹class Container› bool operator==(const queue‹Container›& õ, const queue‹Container›& y) {return õ.ñ == ó.ñ;} template ‹class Container› bool operator‹(const queue‹Container›& õ, const queue‹Container›& y) {return õ.ñ ‹ ó.ñ;} Î÷åðåäü ñ ïðèîðèòåòàìè (Priority queue)Ëþáàÿ ïîñëåäîâàòåëüíîñòü, ñ èòåðàòîðîì ïðîèçâîëüíîãî äîñòóïà è ïîääåðæèâàþùàÿ îïåðàöèè front, push_back è pop_front, ìîæåò èñïîëüçîâàòüñÿ äëÿ ìîäèôèêàöèè priority_queue.  ÷àñòíîñòè, ìîãóò èñïîëüçîâàòüñÿ vector è deque. template ‹class Container, class Compare = less‹Container::value_type› › class priority_queue { public: typedef Container::value_type value_type; typedef Container::size_type size_type; protected: Container c; Compare comp; public: priority_queue(const Compare& õ = Compare()): c(), comp(õ) {} template ‹class InputIterator› priority_queue(InputIterator first, InputIterator last, const Compare& õ = Compare()): c(first, last), comp(x) {make_heap(c.begin(), ñ.end(), comp);} bool empty() const {return c.empty();} size_type size() const {return c.size();} const value_type& top() const {return c.front();} void push(const value_type& õ) { c.push_back(õ); push_heap(c.begin(), c.end(), comp); } void pop() { pop_heap(c.begin(), c.end(), comp); ñ.ðîð_bàñk(); } }; // Íèêàêîå ðàâåíñòâî íå îáåñïå÷èâàåòñÿ Àäàïòåðû èòåðàòîðîâ (Iterator adaptors)Îáðàòíûå èòåðàòîðû (Reverse iterators)Äâóíàïðàâëåííûå èòåðàòîðû è èòåðàòîðû ïðîèçâîëüíîãî äîñòóïà èìåþò ñîîòâåòñòâóþùèå àäàïòåðû îáðàòíûõ èòåðàòîðîâ, êîòîðûå âûïîëíÿþò èòåðàöèè ÷åðåç ñòðóêòóðó äàííûõ â ïðîòèâîïîëîæíîì íàïðàâëåíèè.Îíè èìåþò òå æå ñàìûå ñèãíàòóðû, êàê è ñîîòâåòñòâóþùèå èòåðàòîðû. Ôóíäàìåíòàëüíîå ñîîòíîøåíèå ìåæäó îáðàòíûì èòåðàòîðîì è åãî ñîîòâåòñòâóþùèì èòåðàòîðîì i óñòàíîâëåíî òîæäåñòâîì &*(reverse_iterator(i))==&*(i - 1). Ýòî îòîáðàæåíèå ïðîäèêòîâàíî òåì, ÷òî, â òî âðåìÿ êàê ïîñëå êîíöà ìàññèâà âñåãäà åñòü óêàçàòåëü, ìîæåò íå áûòü äîïóñòèìîãî óêàçàòåëÿ ïåðåä íà÷àëîì ìàññèâà. template ‹class BidirectionalIterator, class T, class Reference = T&, class Distance = ptrdiff_t› class reverse_bidirectionaiIterator : public bidirectional_iterator‹T, Distance› { typedef reverse_bidirectional_iterator‹BidirectionalIterator, T, Reference, Distance› self; friend bool operator==(const self& õ, const self& y); protected: BidirectionalIterator current; public: reverse_bidirectional_iterator() {} reverse_bidirectional_iterator(BidirectionalIterator õ) : current(õ) {} BidirectionalIterator base() {return current;} Reference operator*() const { BidirectionalIterator tmp = current; return *--tmp; } self& operator++() { --current; return *this; } self operator++(int) { self tmp = *this; --current; return tmp; } self& operator--() { ++current; return *this; } self operator--(int) { self tmp = *this; ++current; return tmp; } }; template ‹class BidirectionalIterator, class T, class Reference, class Distance› inline bool operator==(const reverse_bidirectional_iterator‹BidirectionalIterator, T, Reference, Distance›& x, const reverse_bidirectional_iterator‹BidirectionalIterator, T, Reference, Distance›& y) { return x.current==y.current; } template ‹class RandomAccessIterator, class T, class Reference = T&, class Distance = ptrdiff_t› class reverse_iterator: public random_access_iterator‹T, Distance› { typedef reverse_iterator‹RandomAccessIterator, T, Reference, Distance› self; friend bool operator==(const self& x, const self& y); friend bool operator‹(const self& x, const self& y); friend Distance operator-(const self& x, const self& y); friend self operator+(Distance n, const self& x); protected: RandomAccessIterator current; public: reverse_iterator() {} reverse_iterator(RandomAccessIterator x): current (x) {} RandomAccessIterator base() {return current;} Reference operator*() const { RandomAccessIterator tmp = current; return *--tmp; } self& operator++() { --current; return *this; } self operator++(int) { self tmp = *this; --current; return tmp; } self& operator--() { ++current; return *this; } self operator--(int) { self tmp = *this; ++current; return tmp; } self operator+(Distance n) const { return self(current - n); } self& operator+=(Distance n) { current -= n; return *this; } self operator-(Distance n) const { return self(current + n); } self operator-=(Distance n) { current += n; return *this; } Reference operator[](Distance n) {return *(*this + n);} }; template ‹class RandomAccessIterator, class T, class Reference, class Distance› inline bool operator==(const reverse_iterator‹RandomAccessIterator, T, Reference, Distance›& x, const reverse_iterator‹RandomAccessIterator, T, Reference, Distance›& y) { return x.current == y.current; } template ‹class RandomAccessIterator, class T, class Reference, class Distance› inline bool operator‹(const reverse_iterator‹RandomAccessIterator, T, Reference, Distance›& x, const reverse_iterator‹RandomAccessIterator, T, Reference, Distance›& y) { return y.current ‹ x.current; } template ‹class RandomAccessIterator, class T, class Reference, class Distance› inline Distance operator-(const reverse_iterator‹RandomAccessIterator, T, Reference, Distance›& õ, const reverse_iterator‹RandomAccessIterator, T, Reference, Distance›& y) { return y.current - x.current; } template ‹class RandomAccessIterator, class T, class Reference, class Distance› inline reverse_iterator‹RandomAccessIterator, T, Reference, Distance› operator+(Distance n, const reverse_iterator‹RandomAccessIterator, T, Reference, Distance›& x) { return reverse_iterator‹RandomAccessIterator, T, Reference, Distance›(x.current - n); } Èòåðàòîðû âñòàâêè (Insert iterators)×òîáû áûëî âîçìîæíî èìåòü äåëî ñ âñòàâêîé òàêèì æå îáðàçîì, êàê ñ çàïèñüþ â ìàññèâ, â áèáëèîòåêå îáåñïå÷èâàåòñÿ ñïåöèàëüíûé âèä àäàïòåðîâ èòåðàòîðîâ, íàçûâàåìûõ èòåðàòîðàìè âñòàâêè (insert iterators). Ñ îáû÷íûìè êëàññàìè èòåðàòîðîâ while (first!= last) *result++ = *first++; âûçûâàåò êîïèðîâàíèå äèàïàçîíà [first, last) â äèàïàçîí, íà÷èíàþùèéñÿ ñ result. Òîò æå ñàìûé êîä ñ result, ÿâëÿþùèìñÿ èòåðàòîðîì âñòàâêè, âñòàâèò ñîîòâåòñòâóþùèå ýëåìåíòû â êîíòåéíåð. Òàêîé ìåõàíèçì ïîçâîëÿåò âñåì àëãîðèòìàì êîïèðîâàíèÿ â áèáëèîòåêå ðàáîòàòü â ðåæèìå âñòàâêè (insert mode) âìåñòî îáû÷íîãî ðåæèìà íàëîæåíèÿ çàïèñåé. Èòåðàòîð âñòàâêè ñîçäà¸òñÿ èç êîíòåéíåðà è, âîçìîæíî, îäíîãî èç åãî èòåðàòîðîâ, óêàçûâàþùèõ, ãäå âñòàâêà ïðîèñõîäèò, åñëè ýòî íè â íà÷àëå, íè â êîíöå êîíòåéíåðà. Èòåðàòîðû âñòàâêè óäîâëåòâîðÿþò òðåáîâàíèÿì èòåðàòîðîâ âûâîäà. operator* âîçâðàùàåò íåïîñðåäñòâåííî ñàì èòåðàòîð âñòàâêè. Ïðèñâàèâàíèå operator=(const T& õ) îïðåäåëåíî äëÿ èòåðàòîðîâ âñòàâêè, ÷òîáû ðàçðåøèòü çàïèñü â íèõ, îíî âñòàâëÿåò õ ïðÿìî ïåðåä ïîçèöèåé, êóäà èòåðàòîð âñòàâêè óêàçûâàåò. Äðóãèìè ñëîâàìè, èòåðàòîð âñòàâêè ïîäîáåí êóðñîðó, óêàçûâàþùåìó â êîíòåéíåð, ãäå ïðîèñõîäèò âñòàâêà. back_insert_iterator âñòàâëÿåò ýëåìåíòû â êîíöå êîíòåéíåðà, front_insert_iterator âñòàâëÿåò ýëåìåíòû â íà÷àëå êîíòåéíåðà, à insert_iterator âñòàâëÿåò ýëåìåíòû, êóäà èòåðàòîð óêàçûâàåò â êîíòåéíåðå. back_inserter, front_inserter è inserter - òðè ôóíêöèè, ñîçäàþùèå èòåðàòîðû âñòàâêè èç êîíòåéíåðà. template ‹class Container› class back_insert_iterator: public output_iterator { protected: Container& container; public: back_insert_iterator(Container& x): container(x) {} back_insert_iterator ‹Container›& operator=(const Container::value_type& value) { container.push_back(value); return *this; } back_insert_iterator‹Container›& operator*() {return *this;} back_insert_iterator‹Container›& operator++() {return *this;} back_insert_iterator‹Container›& operator++(int) {return *this;} }; template ‹class Container› back_insert_iterator‹Container› back_inserter(Container& x) { return back_insert_iterator‹Container›(x); } template ‹class Container› class front_insert_iterator: public output_iterator { protected: Container& container; public: front_insert_iterator(Container& x): container (x) {} front_insert_iterator‹Container›& operator=(const Container::value_type& value) { container.push_front(value); return *this; } front_insert_iterator‹Container›& operator*() {return *this;} front_insert_iterator‹Container›& operator++() {return *this;} front_insert_iterator‹Container›& operator++(int) {return *this;} }; template ‹class Container› front_insert_iterator‹Container› front_inserter(Container& x) { return front_insert_iterator‹Container›(õ); } template ‹class Container› class insert_iterator: public output_iterator { protected: Container& container; Container::iterator iter; public: insert_iterator(Container& x, Container::iterator i) : container (x), iter(i) {} insert_iterator‹Container›& operator=(const Container::value_type& value) { iter = container.insert(iter, value); ++iter; return *this; } insert_iterator‹Container›& operator*() {return *this;} insert_iterator‹Container›& operator++() {return *this;} insert_iterator‹Container›& operator++(int) {return *this;} }; template ‹class Container, class Iterator› insert_iterator<Container› inserter(Container& x, Iterator i) { return insert_iterator‹Container›(x, Container::iterator(i)); } Àäàïòåðû ôóíêöèé (Function adaptors)Ôóíêöèîíàëüíûå àäàïòåðû ðàáîòàþò òîëüêî ñ êëàññàìè ôóíêöèîíàëüíûõ îáúåêòîâ ñ îïðåäåë¸ííûìè òèïàìè ïàðàìåòðîâ è òèïîì ðåçóëüòàòà. Îòðèöàòåëè (Negators)Îòðèöàòåëè not1 è not2 áåðóò óíàðíûé è áèíàðíûé ïðåäèêàòû ñîîòâåòñòâåííî è âîçâðàùàþò èõ äîïîëíåíèÿ. template ‹class Predicate› class unary_negate: public unary_function‹Predicate::argument_type, bool› { protected: Predicate pred; public: unary_negate(const Predicate& x): pred(x) {} bool operator()(const argument_type& x) const {return !pred(x);} }; template ‹class Predicate› unary_negate‹Predicate› not1(const Predicate& pred) { return unary_negate‹Predicate›(pred); } template ‹class Predicate› class binary_negate: public binary_function‹Predicate::first_argument_type, Predicate::second_argument_type, bool› { protected: Predicate pred; public: binary_negate(const Predicate& x): pred(x) {} bool operator()(const first_argument_type& x, const second_argument_type& y) const { return !pred(x, y); } }; template ‹class Predicate› binary_negate‹Predicate› not2(const Predicate& pred) { return binary_negate‹Predicate›(pred); } Ïðèâÿçêè (Binders)Ïðèâÿçêè bind1st è bind2nd áåðóò ôóíêöèîíàëüíûé îáúåêò f äâóõ ïàðàìåòðîâ è çíà÷åíèå x è âîçâðàùàþò ôóíêöèîíàëüíûé îáúåêò îäíîãî ïàðàìåòðà, ñîçäàííûé èç f ñ ïåðâûì èëè âòîðûì ïàðàìåòðîì ñîîòâåòñòâåííî, ñâÿçàííûì ñ õ. template ‹class Predicate› class binder1st: public unary_function { protected: Operation op; Operation::first_argument_type value; public: binder1st(const Operation& x, const Operation::first_argument_type& y) : op(x), value(y) {} result_type operator()(const argument_type& x) const { return op(value, x); } }; template ‹class Operation, class T› binder1st‹Operation› bind1st(const Operation& op, const T& x) { return binder1st‹Operation›(op, Operation::first_argument_type(x)); } template ‹class Operation› class binder2nd: public unary_function‹0peration::first_argument_type, Operation::result_type› { protected: Operation op; Operation::second_argument_type value; public: binder2nd(const Operation& x, const Operation::second_argument_type& y) : op(x), value(y) {} result_type operator()(const argument_type& x) const { return op(x, value); } }; template ‹class Operation, class T› binder2nd‹Operation› bind2nd(const Operation& op, const T& x) { return binder2nd‹0peration›(op, Operation::second_argument_type(x)); } Íàïðèìåð, find_if(v.begin(), v.end(), bind2nd(greater‹int›(), 5)) íàõîäèò ïåðâîå öåëîå ÷èñëî â âåêòîðå v áîëüøåå, ÷åì 5; find_if(v.begin(), v.end(), bind1st(greater‹int›(), 5)) íàõîäèò ïåðâîå öåëîå ÷èñëî â v ìåíüøåå, ÷åì 5. Àäàïòåðû óêàçàòåëåé íà ôóíêöèè (Adaptors for pointers to functions)×òîáû ïîçâîëèòü óêàçàòåëÿì íà (óíàðíûå è áèíàðíûå) ôóíêöèè ðàáîòàòü ñ ôóíêöèîíàëüíûìè àäàïòåðàìè, áèáëèîòåêà îáåñïå÷èâàåò ñëåäóþùåå: template ‹class Arg, class Result› class pointer_to_unary_function: public unary_function‹Arg, Result› { protected: Result (*ptr)(Arg); public: pointer_to_unary_function() {} pointer_to_unary_function(Result (*x)(Arg)): ptr(x) {} Result operator()(Arg x) const {return ptr(x);} }; template ‹class Arg, class Result› pointer_to_unary_function‹Arg, Result› ptr_fun(Result (*x)(Arg)) { return pointer_to_unary_function‹Arg, Result›(x); } template class pointer_to_binary_function: public binary_function { protected: Result (*ptr)(Arg1, Arg2); public: pointer_to_binary_function() {} pointer_to_binary_function(Result (*x)(Arg1, Arg2)): ptr(õ) {} Result operator()(Arg1 x, Arg2 y) const {return ptr(x, y);} }; template ‹class Arg1, class Arg2, class Result› pointer_to_binary_function‹Arg1, Arg2, Result› ptr_fun(Result (*x)(Arg1, Arg2)) { return pointer_to_binary_function‹Argl, Arg2, Result›(x); } Íàïðèìåð, replace_if(v.begin(), v.end(), not1(bind2nd(ptr_fun(strcmp), "C")), "C++") çàìåíÿåò âñå "Ñ" íà "C++" â ïîñëåäîâàòåëüíîñòè v. Ñèñòåìû òðàíñëÿöèè, êîòîðûå èìåþò ìíîæåñòâåííûé óêàçàòåëü íà òèïû ôóíêöèé, äîëæíû îáåñïå÷èòü äîïîëíèòåëüíûå øàáëîíû ôóíêöèé ptr_fun. |
|
||
Ãëàâíàÿ |  èçáðàííîå | Íàø E-MAIL | Ïðèñëàòü ìàòåðèàë | Íàø¸ë îøèáêó | Íàâåðõ |
||||
|