简体   繁体   English

为什么我需要Forward Iterator来实现我自定义的std :: search

[英]Why do I need a Forward Iterator to implement my customized std::search

I am studying the book "Accelerated C++" from Koenig & Moo. 我正在研究Koenig&Moo的“Accelerated C ++”一书。

Exercise 8-2 ask me to implement on my own some templatized functions from <algorithm> and <numeric> , and to specify what kind of iterator does my implementation require. 练习8-2让我自己实现一些来自<algorithm><numeric>模板化函数,并指定我的实现需要什么样的迭代器。

When trying to implement std::search , I determined that I need only "input" iterators. 在尝试实现std::search ,我确定我只需要“输入”迭代器。

Here is my code so far: 到目前为止,这是我的代码:

template <class In1, class In2>
In1 search(In1 b, In1 e, In2 b2, In2 e2)
{
    if (b2 != e2) {
        while (b != e) {
            if (*b == *b2) {
                In1 bc = b;
                In2 b2c = b2;
                while (bc != e && b2c != e2 && *bc == *b2c) {
                    ++bc;
                    ++b2c;
                }
                if (b2c == e2)
                    return b;
            }
            ++b;
        }
    }
    return e;
}

However, looking at the implementation of std::search installed with my compiler, I can see that they use "forward" iterators, but I cannot understand why, because there is no need to write, only to read, and input iterators meet the requirement. 但是,看看用我的编译器安装的std::search的实现,我可以看到它们使用“前向”迭代器,但我无法理解为什么,因为没有必要编写,只能读取,输入迭代器符合需求。

Can anybody here help me to understand this, please? 请问有人帮我理解这个吗? Why would I need to use "forward" iterators to implement std::search ? 为什么我需要使用“前向”迭代器来实现std::search

With an input iterator, you are only allowed to pass through the range once. 使用输入迭代器,您只能通过该范围一次。 That is, once you've dereferenced and incremented the iterator, you can't go back and dereference it again. 也就是说,一旦你取消引用并递增了迭代器,你就不能再回过头来取消引用它。

This class of iterators is quite useful for many things. 这类迭代器对很多东西都非常有用。 For example, if you are reading from a stream of some kind, once you've read something from the stream you can't go back and read that thing again; 例如,如果您正在阅读某种类型的流,那么一旦您从流中读取了某些内容,就无法再回过头来阅读该内容; you can't store off a copy of the iterator, continue iterating with the original iterator, then go back and start iterating with the copy and assume you'll get the same results. 你不能存储迭代器的副本,继续使用原始迭代器进行迭代,然后返回并开始使用副本进行迭代,并假设你将获得相同的结果。

In your algorithm, you pass through the range more than once (see the comments in your source here): 在您的算法中,您不止一次地通过该范围(请参阅源代码中的注释):

template <class In1, class In2>
In1 search(In1 b, In1 e, In2 b2, In2 e2)
{
    if (b2 != e2) {
        while (b != e) {
            if (*b == *b2) {
                In1 bc = b;            // copy iterator b
                In2 b2c = b2;
                while (bc != e && b2c != e2 && *bc == *b2c) {
                    ++bc;              // increment the copy of iterator b
                    ++b2c;
                }
                if (b2c == e2)
                    return b;
            }
            ++b;                       // increment the original b
        }
    }
    return e;
}

ForwardIterator is the most basic type of iterator that can be used for multi-pass algorithms because it guarantees that you can iterate over a range multiple times. ForwardIterator是最基本的迭代器类型,可用于多次通过算法,因为它可以保证您可以多次迭代一个范围。

Whether an iterator is mutable or immutable (that is, whether you can modify the element to which an iterator of its type refers) is independent of the category of the iterator: a ForwardIterator may be immutable. 迭代器是可变的还是不可变的(即,是否可以修改其类型的迭代器引用的元素)与迭代器的类别无关: ForwardIterator可以是不可变的。 For example, const iterators of any iterator category are immutable (or, for a concrete example, std::forward_list<int>::const_iterator in C++0x is an immutable forward iterator). 例如,任何迭代器类别的const迭代器都是不可变的(或者,对于具体示例,C ++ 0x中的std::forward_list<int>::const_iterator是一个不可变的前向迭代器)。

I think your conclusion that you need only input iterators is incorrect. 我认为你只需要输入迭代器的结论是不正确的。 With an input iterator, you're only allowed to de-reference a particular iterator value once (eg, when you're reading from standard input, two reads will get two separate items, not two references to the same item). 使用输入迭代器,您只能允许一次取消引用特定的迭代器值(例如,当您从标准输入读取时,两次读取将获得两个单独的项目,而不是两个对同一项目的引用)。

Although you've (sort of) hidden it by using copies of the iterators, you still look at the same item(s) twice: 虽然你已经(通过使用迭代器的副本)隐藏它,但你仍然会看两次相同的项目:

// Look at *b and *b2:
        if (*b == *b2) {

            In1 bc = b;
            In2 b2c = b2;

// Now look at the same items again:
            while (bc != e && b2c != e2 && *bc == *b2c) {

Your code depends on dereferencing the same iterators (or, more accurately, different iterators with the same values) twice, so it won't work with input iterators. 您的代码依赖于取消引用相同的迭代器(或更准确地说,具有相同值的不同迭代器)两次,因此它不适用于输入迭代器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM