(Boolan)STLと汎型プログラミングの第四辺メモ(下)

9528 ワード

1.C++標準ライブラリのアルゴリズムは何ですか?言語レベルではSTLのアルゴリズムは次の2つの形になります.
template
Algorithm(Iterator itr1, Iterator itr2)
{
  //...
}
template
Algorithm(Iterator itr1, Iterator itr2, Cmp comp)
{ 
  //...
}
上の二つのものはFunction templateで、一般的なアルゴリズムは二つのバージョンがあります.一つは二つのパラメータで、一つは三つのパラメータがあるバージョンです.前の2つのパラメータは、アルゴリズムに動作が必要なオブジェクトの範囲を知るための2つのサブジェネレータであり、3番目のパラメータは、アルゴリズムの弾力性を高めるためのものであり、ユーザーは、その中に自分の基準を追加することができます.アルゴリズムは容器が見えないので、何も知らないです.すべての情報はiteratorから得られます.iteratorはアルゴリズムとコンテナの間の橋です.
1.1各種容器のiteratorsのiterator_category STLには五中iterator_があります.categoryはそれぞれ:
struct input_iteratorタグstructout put_iteratorタグstruct forward(u)iteratorpublic input_iteratorタグstruct bidirectionaliteratorpublic forward()iteratorタグstruct randomaccess_iteratorpublic bidirectionaliteratorタグAray,Vector,Dequeの3つの容器はランダムアクセスをサポートしています.連続空間です.access_iterator「list、set、map、multiset、multimapは、すべて関連容器です.ランダムアクセスはサポートされていません.bidirectionalを使用しています.」iteratorフォーマット.リスト、アンダードレッドset,unorded_map,unorded_multiset,unorded_multimapは一方向連続空間であり、ランダムアクセスはサポートされていません.iteratoristream、ostreamはそれぞれinput_を使用しています.iteratorえっと、out putですineratortypeid.name()は、直接対象のタイプ名を得ることができます.
1.2 iterator_categoryのアルゴリズムに対する影響はdistance関数を用いてコンテナbeginとendの距離を求める.
template
inline iterator_traits::difference_type
distance(InputIterator first, InputIterator last)
{ 
  typedef typename iterator_traits::iterator_category category;
  return __distance(first, last, category);
}
   vector.begin() vector.end()  ,     iterator_traits    iterator_category  ,     :

template
inline iterator_traits::difference_type
__distance(RandomAccessIterator first, RandomAccessIterator last, input_iterator_tag)
{ 
  return last - first;
}
         ,        ,      ,     
     list.begin() list.end()  ,     iterator_traits    iterator_category  ,     :

template
inline iterator_traits::difference_type
__distance(InputIterator first, InputIterator last, input_iterator_tag)
{ 
  iterator_traits::difference_type n = 0; 
    while(first != last) 
    { 
      ++first; 
      ++n; 
    } 
  return n;
}
非連続空間容器であるため、1つずつ後方向にずらすことで距離が得られます.速度が遅いこれからは想像できますが、違ったiterator_.categoryのアルゴリズムに対する影響は非常に大きい.アルゴリズムでは、非常に多くの検査を行います.アルゴリズムを使って、正確な最速のディズエデーターを分類して容器を操作します.STLを使うのは本当に幸せなことです.
2.アナログ関数は、実際には、クラスのリロード()演算子です.STLでは、次のようになります.
template 
struct plus: public binary_function
{ 
  T operator () (const T& x, const T& y) 
  { 
    return x+y; 
  }
}
   STL    ,             ,         ,  :

//       
bool myfunc(int i, int j)
{ 
  return i < j;
}
sort(myvec.begin(), myvec.end(), myfunc);

//        
template 
struct less: public binary_function
{ 
  bool operator () (const T& x, const T& y) const 
  { 
    return x < y; 
  }
}
sort(myvec.begin(), myvec.end(), less());
less()は一時的なオブジェクトで、それをsortに導入すると、自動的にclass lessの中のoperatorを呼び出します.関数を呼び出すように(関数よりもコピー関数の方が弾性があります.)、コピー関数はアダプターによって修正されます.私達が自分でまねる関数を書いたらSTLの二つの種類を引き継ぐ必要があります.functionmplate struct unary_function{typedef Arg argment_type;typedef Result Result Result;}
//二つの操作数はbinary_を継承します.functionmplate struct binary uFunction{typedef Arg 1 fistugment];typedef Arg 2 secondcunt;typedef Result Result ultype;
STL     Adaptable Function          ,  Function Adapter      ,  :
template class binder 2 nd:public unary_function{protected:Operation op]//ここはfunction adapperが質問しています.typename Operation::secondugment value;
public://….」typename Operation::second_argmenttype value;
            ,            ,           ,                      ,         。
         STL       ,           STL。

3. Adapter
STL              ,                 ,                  ,           ,                   。

3.1 bind2nd
     count_if  :
template typename iterator utrits:difference_type count_if(Input Iterator first、Input Iterator last、Predicate pred){typename iterators}{difference n=0;for(;first!=last;+first){first)}{first}を使用します.if時は以下の通りです
count_if(vi.begin()、vi.end()、bind 2 nd(less()、40);bind 2 ndは、アナログ関数lessの第二パラメータを40にバインドするアダプターである.bind 2 ndソースは以下の通りです.
template inline binder 2 nd binder 2 nd(const Operation&op、const T&x){typename Operation::secondugment arg 2 lt;return binder 2 nd(op、arg 2 up(x);
 bind2nd       binder2nd       ,bind2nd          ,  binder2nd              ,        ,                 Operation。
class binder2nd    :
template class binder 2 nd:public unary_function typename Operation:reult_type>{protected:Operation op;typename Operation::seconduugggments value;public:binder2 nd(const Operation&x、const typename Operation::secondugurgutytytytytytytytytypepepepepepepepepepepepepepepepepepepetytytytytytytytytytytytytytytytytytytytytytytytytytytytytytytytytytytytytytytytytytytytytytypepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepepeutype&x)const{return op(x,value)}count_ifでは、第3のパラメータbind 2 nd(less()、40)が導入されると、まずbind 2 nd関数を呼び出します.関数はOperationとTのタイプ関数を決定します.
inline binder 2 nd(const less&op,const int&x){typedef less::secondugment 2_tyle;;return binder 2 nd>(op,arg 2_type(x);)を先にclass binder 2 ndパラメータを決定させます.
class binder 2 nd:public unary_function::fist_argmenttype,less:reult_type>{protected:less op;less::secondugment value;public:binder 2 nd(const less&x,const less::secondgutype&y):op(x)、value(y)less:ulrestopter
        class binder2nd     ,     binder2nd       , less() 40     op value  。
  count_if           binder2nd       ,     less 40,count_if      :
//viを加えると容器listの実用化ptrdif_t count_if(list:iterator first、list:iterator last、binder 2 nd pred){ptrdiftut=0;for(;first!=last;+first){if(*first))}rern;
 count_if   pred      (pred  binder2nd          ),   class binder2nd   operator(), operator() 

op(x, 40);
40     less()      
              (       )。
3.2 inserter
     copy             ,          

int myints[] = {10, 20, 30, 40, 50, 60, 70};
vector myvec(7);
copy(myints, myints+7, myvec.begin());
         copy            ,             ,    :
template Output Iterator copy(Input Iterator first、Input Iterator last、Output Iterater reult){while(first!=last)}
               ,      ,      copy           (    ),                    。
 copy             :

copy(myints, myints+7, inserter(myvec, iter)); //iter    ,         
inserter    :
template inline insert_iterator insert(Conttainer&x,Iterator i){typedef typename Continer:iterator;return insertitor(x,iter(i)}}inserterはbind 2 ndと同様に、補助関数であり、class insertを助ける.iteratorはテンプレートパラメータを決定します.class insert_iteratorソースは以下の通りです.
template class insert_iterator-protected:Conttainer*container;typename Continer:iterator iter;public:typedef outputut putation iteratory;
insert_iterator(Container& x, typename Container::iterator i)
    :container(&x), iter(i)
{ }

insert_iterator&
operator = (const typename Container::value_type& value)
{
    iter = container->insert(iter, value);
    return *this;
}

typename Container::iterator& operator ++ ()
{
    return ++iter;
}
inserter      insert_iterator       ,        ,  myvec         container ,myvec    iter            iter , copy     :

result = *first;
++result;
         ,   class insert_iterator           。
  copy          ,             ,                 (C++      ,           )。
4. iostream iterator
                 iostream iterator,  istream_iterator   ostream_iterator,                。
            #include 
4.1 ostream_iterator
ostream_iterator       :
//out_にするitをcout出力デバイスのOtream_に結合します.iteratoout_it(cout)//out_itはcout出力デバイスに結合され、出力要素の後に文字列Otream_を追加します.iteratoout_it(cout,「,」);
include
include
include
include
using namespace std;
int main(){vector vec;for(int i=0;<10;+i){vec.pusic uback(i)];otreamuiterator outit(cout);copy(vec.begin()、vec.end(outit);return 0;
4.2 istream_iterator
      :

//                  
istream_iterator eos;
//               
istream_iterator iit(cin)
  iit = eos ,               ,  iit    ,                
include
include
using namespace std;
int main(){double value 1,value 2;if(iit != eos) { value1 = *iit; } ++iit; if(iit != eos) { value2 = *iit; } cout << value1 << ' ' << value2 << endl; return 0; )
        ,    

cout << "please insert two value: ";
  

istream_iterator iit(cin);
  
        ,    ,          ,cout           ,        ,    iit  ,        iit  ,      ,  cout        。
 :
ifstream infile("./test/01.1 pp")istream_iterator eosistream_iterator iit(infile);
off stream outfile('/.2.cpp);オーストリアiteratoout_it(out file)「」
(  )
        。             ,          。