0

パート 1 を読む必要はないと思いますが、念のためリンクを含めておきます

...イテレータのカテゴリがほぼそこにある(と思う)..さまざまなタイプのイテレータから利用可能な機能を示す簡単なオールインワンのテーブルを見つけるために周りを見回した..見つけられなかったので、私は'v stroustrup のテーブルを拡張して、次のようなものを含めようとしました: 範囲を複数回通過する機能など...何か見逃したり誤解したりした場合はお知らせください。..または、より良いテーブルがあれば

*1++はインクリメント間で (逆) 参照する必要があります

*n++は (逆) 参照せずに複数回インクリメントできます

*n_save範囲は複数回渡して保存/コピーすることができます

------------------------------------------------------------------------------
-  Iterator Operations and Categories                                     
------------------------------------------------------------------------------
Category:        output  input    forward    bidirectional   random-access
Abbreviation:    Out     In       For        Bi              Ran 
------------------------------------------------------------------------------
Read(*1++):              =*p            
Read(*n++):                       =*p        =*p             =*p
Read(*n_save):                    =*p        =*p             =*p

Write(*1++):     *p=             
Write(*n++):                      *p=        *p=             *p=
Write(*n_save):                   *p=        *p=             *p=

Access:                   ->      ->         ->              ->[]

Iteration:        ++      ++      ++         ++--            ++ -- + - += -=
Comparison:               == !=   == !=      == !=           == != < > >= <= 
------------------------------------------------------------------------------

Write(*n_save) ... iter のコピー/保存が読み取りか書き込みかわからなかったので、両方に追加しましたか? ..範囲を複数回読み取り渡すことができるかどうかを推測しています..範囲を複数回書き込み渡すこともできますか?

std::search が前方反復子を必要とする理由を理解しましたが、なぜ 4 が必要なのかわかりません.. 2 For & 2 In十分でしょうか?

while (  begin != end  ) {     
if( begin2 == end2 ) {  return found ;  }
}

.. endend2が複数回参照されているためですか( while ループするたびに)..?

template <class For, class In> 
For search(  For begin, In end, For begin2, In end2 )
{
    For found ;                     
    For pattern_begin = begin2 ;    //refd
    int flag = 0 ;                  

    // search content for pattern 
    while (  begin != end  ) {      //refd

        if ( *begin != *begin2 ) {    //de-refd

            begin2 = pattern_begin ;  //store/copy
            flag = 0 ;
            begin++ ;             //inc


        } else {

            if ( flag == 0 ) { 

                found = begin ;
                flag = 1 ;
            }

            begin++ ;
            begin2++ ;
        }

        if( begin2 == end2 ) {  return found ;  } //refd

    }

    return begin ;
}
4

1 に答える 1

0

薄気味悪い空気から「間接参照の間に増分する必要がある」を引き出したと思います。

入出力演算子はそれらを実装しているので、特にそれらを予期しない関数で使用できますが、本質的にインクリメントすることはそれらを使用しない場合があります。

その検索関数には4つのイテレータが必要です。そうしないと、どちらの範囲がどこで終了するかを判断する方法がないためです。イテレータ自体は、(必然的に)範囲の終わりにあるかどうかを知りません。

SC ++ Lの範囲は、同じタイプのイテレーターのペアで表されます。技術的には、アルゴリズムは単一の範囲に対して異なるタイプのイテレータを受け入れることができますが、それはほとんど実用的ではなく、コードをよりエラーが発生しやすくします。現状では、コンパイル時に少なくとも1種類のエラーを検出できます。

void foo(container& a, const container& b, const container& c) {
    std::search(a.begin(), b.end(), c.begin(), c.end());
}

ここでのエラーは、最初の2つの引数のイテレータを異なるコンテナに渡すことです。ただし、この場合、これはコンパイル時にキャッチされます。これは、幸いなことにabたまたま異なる定数を持っているため、異なるタイプをa.begin()返しcontainer::iteratorたり返したりするためです。4つの引数すべてが異なるタイプであることが許可されている場合、このエラーにより、実行時に未定義の動作が発生します。b.end()container::const_iterator

于 2011-03-23T22:24:36.193 に答える