繁体   English   中英

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

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

我正在研究Koenig&Moo的“Accelerated C ++”一书。

练习8-2让我自己实现一些来自<algorithm><numeric>模板化函数,并指定我的实现需要什么样的迭代器。

在尝试实现std::search ,我确定我只需要“输入”迭代器。

到目前为止,这是我的代码:

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;
}

但是,看看用我的编译器安装的std::search的实现,我可以看到它们使用“前向”迭代器,但我无法理解为什么,因为没有必要编写,只能读取,输入迭代器符合需求。

请问有人帮我理解这个吗? 为什么我需要使用“前向”迭代器来实现std::search

使用输入迭代器,您只能通过该范围一次。 也就是说,一旦你取消引用并递增了迭代器,你就不能再回过头来取消引用它。

这类迭代器对很多东西都非常有用。 例如,如果您正在阅读某种类型的流,那么一旦您从流中读取了某些内容,就无法再回过头来阅读该内容; 你不能存储迭代器的副本,继续使用原始迭代器进行迭代,然后返回并开始使用副本进行迭代,并假设你将获得相同的结果。

在您的算法中,您不止一次地通过该范围(请参阅源代码中的注释):

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是最基本的迭代器类型,可用于多次通过算法,因为它可以保证您可以多次迭代一个范围。

迭代器是可变的还是不可变的(即,是否可以修改其类型的迭代器引用的元素)与迭代器的类别无关: ForwardIterator可以是不可变的。 例如,任何迭代器类别的const迭代器都是不可变的(或者,对于具体示例,C ++ 0x中的std::forward_list<int>::const_iterator是一个不可变的前向迭代器)。

我认为你只需要输入迭代器的结论是不正确的。 使用输入迭代器,您只能允许一次取消引用特定的迭代器值(例如,当您从标准输入读取时,两次读取将获得两个单独的项目,而不是两个对同一项目的引用)。

虽然你已经(通过使用迭代器的副本)隐藏它,但你仍然会看两次相同的项目:

// 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) {

您的代码依赖于取消引用相同的迭代器(或更准确地说,具有相同值的不同迭代器)两次,因此它不适用于输入迭代器。

暂无
暂无

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

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