【问题标题】:PART 2 : Why do I need a Forward Iterator to implement my customized std::search第 2 部分:为什么我需要前向迭代器来实现我的自定义 std::search
【发布时间】:2011-03-23 22:14:39
【问题描述】:

认为没有必要阅读第一部分,但我将包含链接以防万一: why does std::search need forward iters

.....几乎有迭代器类别(我认为)..我环顾四周找到了一个简单的多合一表,它显示了各种类型的迭代器提供的功能..找不到一个,所以我试图扩展 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 ;  }
}

..是不是因为 end 和 end2 被多次引用(每次 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 ;
}

【问题讨论】:

    标签: c++ iterator forward


    【解决方案1】:

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

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

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

    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::iterator 和 b.end() 返回不同的类型 container::const_iterator。如果允许所有四个参数为不同类型,则此错误将导致运行时未定义的行为。

    【讨论】:

    • sry 我的意思是在取消引用之间增加不止一次
    • 我得到“搜索”需要 4 次迭代……但它们都需要 For
    • @tuk: 第一个和第二个参数是同一类型,第三个和第四个是另一个类型。我想它们有可能是所有不同的类型,但话又说回来,在什么情况下你会通过比较前向迭代器和输入迭代器得到有意义的结果? - 一个范围是由一对相同类型的迭代器描述的,除了我们在技术上可以做到的之外,为什么要让它比这更令人困惑?
    • 感谢 UncleBens 澄清 ..dunno 为什么我发现很难掌握这个迭代器 malarkey .. 每次我认为我已经掌握了它.. 其他东西会弹出来表明我还没有:)
    猜你喜欢
    • 1970-01-01
    • 2011-07-19
    • 2017-02-19
    • 1970-01-01
    • 2019-08-13
    • 2011-04-30
    • 1970-01-01
    • 2010-11-16
    • 1970-01-01
    相关资源
    最近更新 更多