第2部分:为什么我需要一个Forward Iterator来实现我自定义的std :: search

时间:2011-03-23 22:14:40

标签: c++ iterator forward

不要认为有必要阅读第一部分,但我只是包含链接: why does std::search need forward iters

.....几乎与迭代器类似(我认为)..我环顾四周找到一个简单的一体化表,它显示了各种类型的迭代器提供的功能..无法找到所以我试图扩展stroustrup的表格,包括:不止一次超越范围的能力等等......让我知道我是否错过或误解了什么? ..或者,如果有一个更好的桌子踢

必须在增量

之间引用

* 1 ++

* n ++ 可以多次递增而不被(de)引用

* 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:               == !=   == !=      == !=           == != < > >= <= 
------------------------------------------------------------------------------

写(* n_save) ...不确定是否读取或写入了复制/保存it ..所以我将它添加到两者中? ..我猜你是否可以多次读取一个范围..你可能还想写一个范围不止一次?

我现在明白为什么std :: search需要转发迭代器,但不确定为什么它需要4 ..would 2 For&amp; 2足够吗?

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

..是因为结束 end2 被多次refd(每次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 ;
}

1 个答案:

答案 0 :(得分:0)

我认为你已经拉开了“必须在解除引用之间递增”。

输入和输出操作符实现它们,以便它们可以被一个特别不期望它们的函数使用,但基本上递增可能是与它们无关。

该搜索函数需要四个迭代器,因为否则就无法确定任何一个范围结束的位置。迭代器本身并不(必然)知道它是否在范围的末尾。

SC ++ L中的范围由一对相同类型的迭代器表示。从技术上讲,算法可以接受单个范围的不同类型的迭代器,但这几乎没有任何实际用途,只是使代码更容易出错。实际上,在编译时至少可以检测到一种错误:

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

这里的错误是将迭代器传递给前两个参数的不同容器。但在这种情况下,这将在编译时被捕获,因为幸运的是ab恰好具有不同的常量,因此a.begin()返回container::iteratorb.end()返回不同的类型container::const_iterator。如果允许所有四个参数都是不同类型,则此错误将导致运行时未定义的行为。