<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                定義:將一個class的接口轉換為另一個class的接口,使原本因接口不兼容而不能合作的classes,可以一起運作。適配器扮演者軸承、轉換器的角色。 分類: 1、容器適配器:改變容器接口。 STL提供兩個容器迭代器:queue和stack。它們都是修飾deque后成為另一種風貌的容器。 2、迭代器適配器:改變迭代器接口。 - Insert Iterator:將容器綁定到back_insert_iterator、front_insert_iterator、insert_iterator。它們都是一個類,對它們的賦值操作將轉換為對綁定容器的插入操作。為了操作方便,向用戶提供的是一個函數,函數中才創建上述類。 以back_inserter為例: ~~~ template <class Container> inline back_insert_iterator<Container> back_inserter(Container& x) { return back_insert_iterator<Container>(x); // 以容器為參數,創建迭代器適配器 } ~~~ 注意,一般迭代器適配器不會以迭代器作為參數,這里通過傳入一個容器創建一個迭代器適配器。 下面是back_insert_iterator類的定義: ~~~ template <class Container> class back_insert_iterator { protected: Container* container; // 注意,這里是一個指向容器的指針 public: typedef output_iterator_tag iterator_category; // 輸出迭代器,只支持自增 typedef void value_type; typedef void difference_type; typedef void pointer; typedef void reference; explicit back_insert_iterator(Container& x) : container(&x) {} // 與容器相綁定 back_insert_iterator<Container>& operator=(const typename 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; } }; ~~~ 可以看到,迭代器適配器提供了自增和接引用的接口,但是實際的功能被關閉了。上述代碼的關鍵在于,對迭代器適配器的賦值變為了對容器的插入操作。 下面是我自己寫的一個類似于上面的迭代器適配器: ~~~ #include <iostream> #include <vector> using namespace std; template <class Container> class my_back_insert_iterator { protected: Container* container; public: explicit my_back_insert_iterator(Container& x) : container(&x) {} my_back_insert_iterator<Container>& operator=(const typename Container::value_type& value) { container->push_back(value); return *this; } }; int main() { vector<int> vec; my_back_insert_iterator< vector<int> > back_insert(vec); back_insert = 1; back_insert = 2; back_insert = 3; back_insert = 4; vector<int>::iterator iter = vec.begin(); for ( ; iter != vec.end(); ++iter) cout << *iter << endl; return 0; } ~~~ 運行結果: ![](https://box.kancloud.cn/2016-08-11_57ac4c8b845d7.jpg) 對迭代器的賦值即是對容器的插入操作。 - Reverse Iterator:使迭代器行進方向逆轉。逆向迭代器一般用在容器中,容器都會提供一些接口,如下所示,使它可以和某些算法配合,逆向完成某些操作。 容器中的接口如下: ~~~ reverse_iterator rbegin() { return reverse_iterator(end()); } reverse_iterator rend() { return reverse_iterator(begin()); } ~~~ 在看一下reverse_iterator的構造函數: ~~~ Iterator current; // 保存傳入的迭代器 .... typedef Iterator iterator_type; typedef reverse_iterator<Iterator> self; explicit reverse_iterator(iterator_type x) : current(x) {} // 構造函數 ~~~ 構造函數的任務就是把傳入的迭代器保存在內部的current中。 下面是反向迭代器的關鍵所在: ~~~ reference operator*() const { Iterator tmp = current; return *--tmp; // 先自減,再接引用 } self& operator++() { --current; return *this; } self& operator--() { ++current; return *this; } ~~~ 這里要注意的是接引用操作,先要把迭代器減1,這樣才能保證對尾端元素的接引用是正確的。 測試代碼如下: ~~~ int a[] = {9,5,4,8,3,6,7}; reverse_iterator<int*> reverite(a+7); cout << *reverite++ << " "; cout << *reverite++ << " "; cout << *reverite++ << " "; ~~~ 運行結果: ![](https://box.kancloud.cn/2016-08-11_57ac4c8b999ef.jpg) - IOStream Iterator:將迭代器(istream_iterator或ostream_iterator)綁定到某個iostream對象(cin/cout)上,從而操作這些IO對象。 以綁定標準輸出為例,測試代碼如下: ~~~ int a[] = {9,5,4,8,3,6,7}; ostream_iterator<int> outite(cout, " "); // 輸出數組元素時附帶輸出空格 copy(a, a+7, outite); ~~~ 運行結果: ![](https://box.kancloud.cn/2016-08-11_57ac4c8bb57a9.jpg) 上述代碼將迭代器適配器綁定到標準輸出,并且每輸出一個元素,附帶輸出一個空格符。對迭代器的賦值(operator=)就是對它的輸出操作(operator<<)。源代碼如下: ~~~ template <class T> class ostream_iterator { protected: ostream* stream; // 綁定的標準輸出 const char* string; // 分隔符 public: typedef output_iterator_tag iterator_category; typedef void value_type; typedef void difference_type; typedef void pointer; typedef void reference; ostream_iterator(ostream& s) : stream(&s), string(0) {} ostream_iterator(ostream& s, const char* c) : stream(&s), string(c) {} ostream_iterator<T>& operator=(const T& value) { *stream << value; // 關鍵點 if (string) *stream << string; // 輸出間隔符 return *this; } // 以下三個操作都返回自己 ostream_iterator<T>& operator*() { return *this; } ostream_iterator<T>& operator++() { return *this; } ostream_iterator<T>& operator++(int) { return *this; } }; ~~~ 注意最后三個操作都只是本身,這樣做的目的是可以配合copy()等算法: *result = *first; result就是該迭代器,對它接引用然后進行賦值操作將調用上面的operator=函數,使得copy()算法能夠把一段范圍內的元素輸出到標準輸出。這也正是泛型算法的精妙之處:算法只負責做固定工作,至于具體如何實現,由各個迭代器來完成。 3、函數適配器:改變仿函數/函數接口,用于特化和擴展一元和二元函數對象,使其能夠適應STL算法的參? ? ? 數接口。標準庫將它分兩類: - 綁定器(bind1st/bind2nd):將一個操作數綁定到給定值而將二元函數對象轉換為一元函數對象。 - 求反器:將謂詞函數對象的真值求反。 以count_if為例,應用程序調用如下代碼: ~~~ // 計算容器中小于等于3的元素個數 cout << count_if(vec.begin(), vec.end(), bind2nd(less_equal<int>(), 3)); ~~~ 則會調用如下函數: ~~~ template <class InputIterator, class Predicate, class Size> void count_if(InputIterator first, InputIterator last, Predicate pred, Size& n) { for ( ; first != last; ++first) if (pred(*first)) /* 對每個元素調用仿函數 */ ++n; /* 滿足條件則累加 */ } ~~~ 下面看看pred,也就是bind2nd的源代碼: ~~~ template <class Operation> class binder2nd : public unary_function<typename Operation::first_argument_type, typename Operation::result_type> { protected: Operation op; typename Operation::second_argument_type value; public: binder2nd(const Operation& x, // 仿函數 const typename Operation::second_argument_type& y) // 綁定的第二個數 : op(x), value(y) {} typename Operation::result_type operator()(const typename Operation::first_argument_type& x) const { return op(x, value); // 關鍵點 } }; ~~~ 代碼一目了然。需要注意一點,此函數適配器必須要繼承自unary_function對象,滿足可配接性。解釋一下可配接性。less_equal類繼承自binary_function,便有了內部嵌套類型second_argument_type,而這個類型正好需要用在binder2nd中,以保存(綁定)某個參數。這樣,less_equal就變為了可配接的。如果還有其它的適配器需要繼續作用在binder2nd上,那么binder2nd也需要提供這樣的嵌套類型,使它變為可配接的。這在另一篇文章“<ch07>仿函數”中也有所說明。 總結: 縱觀整個適配器系統,基本上都是把某個對象或指向對象的指針封裝在一個適配器類中,對適配器的操作最終都會傳遞到對所包含對象的操作上來。 參考: 《C++ primer》 P453. 《STL源碼剖析》 第八章。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看