(Boolan)STLと汎型プログラミングの第四辺メモ(下)
9528 ワード
1.C++標準ライブラリのアルゴリズムは何ですか?言語レベルではSTLのアルゴリズムは次の2つの形になります.
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の距離を求める.
2.アナログ関数は、実際には、クラスのリロード()演算子です.STLでは、次のようになります.
//二つの操作数はbinary_を継承します.functionmplate struct binary uFunction{typedef Arg 1 fistugment];typedef Arg 2 secondcunt;typedef Result Result ultype;
public://….」typename Operation::second_argmenttype value;
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);
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
template class insert_iterator-protected:Conttainer*container;typename Continer:iterator iter;public:typedef outputut putation iteratory;
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;
include
using namespace std;
int main(){double value 1,value 2;
off stream outfile('/.2.cpp);オーストリアiteratoout_it(out file)「」
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 ,
includeinclude
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)「」
( )
。 , 。