簡體   English   中英

對“std::istreambuf_iterator”的使用感到困惑

[英]Confused about usage of 'std::istreambuf_iterator'

以下是 來自 cppreference.com 的示例

The Code is:
#include <vector>
#include <sstream>
#include <iostream>
#include <iterator>

int main()
{
// typical use case: an input stream represented as a pair of iterators
std::istringstream in("Hello, world");
std::vector<char> v( (std::istreambuf_iterator<char>(in)),
                      std::istreambuf_iterator<char>() );
std::cout << "v has " << v.size() << " bytes. ";
v.push_back('\0');
std::cout << "it holds \"" << &v[0] << "\"\n";


// demonstration of the single-pass nature
std::istringstream s("abc");
std::istreambuf_iterator<char> i1(s), i2(s);
std::cout << "i1 returns " << *i1 << '\n'
          << "i2 returns " << *i2 << '\n';
++i1;
std::cout << "after incrementing i1, but not i2\n"
          << "i1 returns " << *i1 << '\n'
          << "i2 returns " << *i2 << '\n';
++i2; // this makes the apparent value of *i2 to jump from 'a' to 'c'
std::cout << "after incrementing i2, but not i1\n"
          << "i1 returns " << *i1 << '\n'
          << "i2 returns " << *i2 << '\n';

}

我有兩個問題:

  1. 有人可以詳細說明代碼std::vector<char> v( (std::istreambuf_iterator<char>(in)), std::istreambuf_iterator<char>() ); ,我不太明白它在做什么......以及為什么我們可以僅使用cout<<&v[0]來打印字符串“Hello, world”
  2. 為什么 *i2 的 apprent 值從“a”跳到“c”? 有人可以解釋它的機制嗎?

非常感謝!

有人能詳細說明一下代碼嗎...

std::vector<T>有一個構造函數,它在<T>上有兩個迭代器——一個用於范圍的開頭,一個用於范圍的結尾。

該構造使得從輸入流的輸入流迭代器in

std::istreambuf_iterator<char>(in)

您可以繼續訪問其元素,直到到達流的末尾。 一旦到達流的末尾,迭代器就等同於使用默認構造函數創建的迭代器:

std::istreambuf_iterator<char>()

因此,傳遞這對迭代器會根據從輸入流讀取的數據構造一個vector<T> 整個流將被消耗。

為什么*i2的 apprent 值從"a"跳到"c"

兩個迭代器都從同一個流中讀取。 當您增加第一個迭代器時,它會從底層流中消耗'b' 同時, i2指的是流的第一個字符,它在構建時沒有前進。

一旦你增加i2 ,它就會向流詢問下一個字符。 字符'b'已被消耗,所以下一個字符是'c'

最后,該代碼引入了一個您可能忽略的小技巧:它將一個空終止符推入vector<char>中,以便能夠使用operator <<(...)const char*重載來打印向量。

默認構造的istreambuf_iterator基本上是一個文件結束迭代器——也就是說,只有當另一個迭代器到達文件末尾時,它才會與它比較。

因此,代碼:

std::vector<char> v( (std::istreambuf_iterator<char>(in)),
                      std::istreambuf_iterator<char>() );

...從in讀取char s in直到第一個迭代器增加到等於第二個迭代器,這發生在(並且僅當)第一個迭代器到達文件末尾(在本例中為 stringstream)。 簡而言之,它將文件的全部內容復制到向量中。

打印“hello world”部分要簡單一些:ostream 有一個operator<< char *重載,它假設char *指向一個 C 風格的字符串,所以它應該打印出指向的整個字符串。 由於他們已經執行push_back向字符串添加'\\0' ,這使其成為 C 樣式字符串。

第二部分演示了即使您有兩個迭代器進入流,您仍然只有一個流,並且在該流中只有一個讀取位置。 同時,每個迭代器都持有它從流中讀取的最新項目的副本。

因此,無論何時您增加任一迭代器(或任何迭代器到同一流中),它都會增加當前讀取位置。 因此,您從i1i2開始,它們都指向流的開頭。 然后你增加i1 這會增加讀取位置,並將b讀入i1 ,因此當您取消引用i1 ,這就是您將得到的。 當您增加i2 ,再次移動讀取位置,並將c讀入i2 ,因此取消引用i2將給出c

使用兩個(或更多)迭代器不會改變流的性質——每次你將任何迭代器增加到同一個流中,從該流中讀取下一個項目——並且“下一個項目”總是被確定由流本身,基於其一個讀取位置。

暫無
暫無

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

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