簡體   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