簡體   English   中英

為什么std :: generate()和std :: generate_n()需要不同的迭代器?

[英]Why do std::generate() and std::generate_n() require different iterators?

我在cppreference中查看generate()generate_n()並試圖理解為什么generate()需要ForwardIterator ,而generate_n()需要OutputIterator作為范圍? (我檢查了標准的最新工作草案,這是相同的要求。)

因為,至少他們可能的實現似乎需要相同的迭代器概念,而OutputIterator似乎就足夠了:

generate()

template<class ForwardIt, class Generator>
void generate(ForwardIt first, ForwardIt last, Generator g)
{
    while (first != last) {
        *first++ = g();
    }
}

generate_n()

template<class OutputIt, class Size, class Generator>
OutputIt generate_n(OutputIt first, Size count, Generator g)
{
    for (Size i = 0; i < count; i++) {
        *first++ = g();
    }
    return first;
}

std::fill()std::fill_n()相同的故事。

至少他們可能的實現似乎需要相同的迭代器概念,而OutputIterator似乎就足夠了

OutputIterator不支持相等/不等式比較(包括operator!=在您顯示的generate()的可能實現中使用)和多通道保證,而ForwardIterator則支持。 這意味着OutputIterator不能用於通過兩個迭代器(例如[first, last) )來表示范圍[first, last)這是generate()接口所需要的。

可能沒有為輸出迭代器定義平等和不平等。 即使定義了運算符==,x == y也不需要暗示++ x == ++ y。

songyuanyao的回答從技術角度解釋了這個問題。 我會嘗試提供一些非正式的解釋。

許多STL算法(包括generatefill )都應用於許多項目。 算法必須能夠訪問這些項的方式定義了迭代器的要求。

在您的情況下, generate的定義包含:

...
while (first != last) {  // implies that Iter implements operator!=
  *first++;              // implies that Iter implements operator++

雖然第二個要求似乎滿足任何迭代器類型(畢竟,這就是迭代器的全部內容 - 迭代事物:)),並非所有迭代器類型都提供對比較運算符operator!=的支持。

例如,您不能將ostream_iterator用於std::generate 但是,可以, 例如 ,輸出固定數量的產生的值轉換成經由流std::generate_n

這是Coliru一個非常人為的例子 一旦我開始考慮實際應用程序,我猜想使用OutputIterators的能力可能對實現一些序列化邏輯很有用。

與所有標准庫算法一樣, generate()generate_n()在一個范圍上運行 ,即通過迭代器訪問的一系列值。 為了將操作應用於范圍的所有元素,算法必須知道范圍的開始位置和結束位置。 給它提供信息的常用方法有兩種:你可以用迭代器和長度指定范圍,並使用形式的循環while (length-- != 0) { ... ++first; } while (length-- != 0) { ... ++first; } ; 或者您可以使用一對迭代器[first, last)指定范圍並使用形式的循環while (first != last) { ... ++first; } while (first != last) { ... ++first; }

對於第一個版本,您需要能夠遞增迭代器,並且對於這些算法,通過迭代器寫入值。 這些是輸出迭代器的主要優點,而這就是generate_n()需要的。

對於第二個版本,您需要能夠增加迭代器並通過迭代器寫入值,就像第一個版本一樣。 必須能夠比較兩個迭代器的相等性,並且輸出迭代器不支持它; 你必須至少擁有一個前向迭代器 這就是為什么generate() ,它采用一對迭代器指定的范圍,需要一個前向迭代器。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM