0

不要认为有必要阅读第一部分,但我会包含链接以防万一: 为什么 std::search 需要转发迭代

.....几乎有迭代器类别(我认为)..我环顾四周找到了一个简单的多合一表,它显示了各种类型的迭代器提供的功能..找不到一个所以我'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) ...不确定复制/保存迭代器是读取还是写入..所以我将它添加到两者?..我猜您是否可以多次读取传递范围..您可能还想多次写入传递范围?

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

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

我认为您已经凭空提出了“必须在取消引用之间增加”。

输入和输出运算符实现了这些,因此它们可以被一个不特别期望它们的函数使用,但本质上递增很可能对它们来说是无操作的。

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

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

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

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

于 2011-03-23T22:24:36.193 回答