簡體   English   中英

std :: copy如何與流迭代器一起使用

[英]How does std::copy work with stream iterators

通常的STL結構是:

vector<string> col;
copy(istream_iterator<string>(cin), istream_iterator<string>(),
    back_inserter(col));

我們使用istream_iterator從std輸入( cin )復制到向量。

誰能解釋一下這段代碼的工作原理

我的問題是我真的不明白這一部分:

istream_iterator<string>(cin), istream_iterator<string>()

首先,請注意,在這種情況下,根本不需要使用std::copy 您可以直接從迭代器初始化向量:

vector<string> col((istream_iterator<string>(cin)),
                    istream_iterator<string>());

這可能不會使代碼更容易理解。

至於代碼如何工作,它可能比你想象的更直接。 一個istream_iterator看起來像這樣:

template <class T>
class istream_iterator { 
    std::istream *is;
    T data;
public:
    istream_iterator(std::istream &is) : is(&is) { ++(*this); }
    istream_iterator() : is(nullptr) {}

    T operator++() { (*is) >> data; return *this; }
    T operator++(int) { (*is) >> data; return *this; }

    T const &operator*() { return data; }   

    bool operator !=(istream_iterator &end) { return (*is).good(); }
    bool operator ==(istream_iterator &end) { return !(*is).good(); }
};

顯然,我正在跳過更多,但這是我們關心的大部分內容。 因此,當您創建迭代器時,它會將流中的項讀取(或嘗試)到我稱為data的變量中。 取消引用迭代器時,它會返回data 當您遞增迭代器時,它會讀取(或嘗試)文件中的下一個項目。 盡管編寫好像將一個迭代器與另一個迭代器進行比較,但operator==operator!=實際上只是檢查文件的結尾1

然后由std::copy ,(再次簡化)看起來像這樣模糊:

template <class InIt, class OutIt>
void std::copy(InIt b, InIt e, OutIt d) { 
    while (b != e) {
        *d = *b;
        ++b;
        ++d;
    }
}

因此,這將從輸入迭代器讀取和輸入項,將該項寫入輸出迭代器,並重復直到當前位置的迭代器與輸入結束的迭代器相比(當到達結束時將發生這種情況)文件)。 請注意,與其他迭代器不同,您允許與istream迭代器一起使用的唯一“結束”位置是文件的末尾。


  1. 請注意,從技術上講,這不符合行為。 我簡化了比較以保持簡單。 兩個默認構造的迭代器應該比較相等,如果從同一個流構造兩個迭代器,它們應該至少在從流中讀取任何內容之前進行比較。 這雖然沒有什么實際區別 - 你在實際使用中看到的唯一比較是確定你是否已經到達文件的末尾。

以下部分答案引自C ++標准庫:Nicolai M. Josuttis的教程和參考文章,稍作調整。

表達方式

  istream_iterator<string>(cin) 

創建一個從標准輸入流cin讀取的字符串迭代器。 模板參數string指定流迭代器讀取此類型的元素。 使用通常的輸入運算符>>讀取這些元素。 因此,每次算法想要處理下一個元素時,istream迭代器將該期望轉換為調用

 cin >> string 

字符串的輸入運算符通常讀取由空格分隔的一個單詞。

表達方式

 istream_iterator<string>() 

調用istream迭代器的默認構造函數,它創建一個所謂的end-of-stream迭代器。 它表示您無法再讀取的流。 字符串結束迭代器用作end of the rangeend of the range ,因此算法copycin讀取所有字符串,直到它不再能夠讀取為止。

最后一個:

back_inserter(col))

根據back_inserter文檔:

一個std :: back_insert_iterator,可用於將元素添加到容器c的末尾

它會將所有讀入的字符串添加到col

有關詳細信息,請參閱有關std :: istream_iteratorstd :: back_inserter的信息。

暫無
暫無

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

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