2013-04-29 86 views
7

根據大多數C++引用,例如cplusplus.com,forward iterators不需要是可分配的(我的意思是,推定爲左值)。然而,對於需要編寫值幾個STL算法,例如std::fill(也std::generate等),該規範使用前向迭代:STL填充和轉發迭代器

template <class ForwardIterator, class T> 
    void fill (ForwardIterator first, ForwardIterator last, const T& val); 

而等效行爲,需要左值解除引用:

template <class ForwardIterator, class T> 
    void fill (ForwardIterator first, ForwardIterator last, const T& val) 
{ 
    while (first != last) { 
    *first = val; 
    ++first; 
    } 
} 

所以,它實際上使用了一次可變的前向迭代器。

現在的問題是:

(1)爲什麼不說清楚,在這些情況下使用的前向迭代器是可變的?

(2)更新:我發現下面的問題很愚蠢:我暫時忘了輸出迭代器不需要支持相等比較。無論如何,上述問題依然存在。

爲什麼用std::fillstd::generate等等,而不是實際上需要多次通過使用正向迭代器,而不是輸出迭代器? (std::copy只需要輸出迭代,比如,什麼道理呢?)

+0

'前向迭代器不需要可分配',你是如何確定的?我很確定他們是可分配的。 – 2013-04-29 23:57:44

+0

@JesseGood出於實用目的,它們幾乎總是可分配的,但如果您閱讀了參考文獻http://cplusplus.com/reference/iterator/ForwardIterator/?kw=forward%20iterator,則不是。 – 4ae1e1 2013-04-30 00:01:17

+1

@JesseGood我也在SO上發現了這個:http://stackoverflow.com/questions/14058642/are-forward-iterators-output-iterators – 4ae1e1 2013-04-30 00:03:11

回答

5

從簽名

template <class ForwardIterator, class T> 
void fill (ForwardIterator first, ForwardIterator last, const T& val); 

你不能推斷ForwardIteratorforward iterator描述的迭代器。但是,如果你讀的參數說明,你會發現,firstlast必須

Forward Iterators的最初和最後的位置在支持被分配T類型的價值元素的序列。

(強調我)。因此,只滿足前向迭代器所需要的前向迭代器不是一個有效的參數。

+0

是的,這是一個很好的觀點。但從標準的角度來看簽名是棘手的。 – 4ae1e1 2013-04-30 00:27:46

+0

另一種方法是爲前向迭代器引入一個新的名稱,該名稱支持指向元素的分配。 – Oswald 2013-04-30 00:33:50

1

對我來說這似乎並不奇怪,因爲fill的規範是(取消引用的)迭代器可從T分配。輸出迭代器將不足以用於確定範圍結束,因此選擇了具有要求的forward_iterator

你會注意到,fill_n確實使用輸出迭代,因爲不需要迭代器比較,以確定序列的末端,以填補。

+0

我認爲OP的觀點是前向迭代器的概念是* required *但不*足夠*來指定參數類型的需求。這同樣適用於「輸出迭代器」;只有通過要求參數是*兩者*才能得到正確的語義。換句話說,有不能調用'std :: fill'的前向迭代器。 – 2013-04-30 01:21:15