![](/img/trans.png)
[英]PART 2 : Why do I need a Forward Iterator to implement my customized 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.