日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

插入迭代器、流迭代器、反向迭代器、移动迭代器

發布時間:2023/12/13 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 插入迭代器、流迭代器、反向迭代器、移动迭代器 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 前言
  • 插入迭代器
    • inserter
    • front_inserter
    • back_inserter
  • iostream迭代器
    • istream_iterator 讀取輸入流
      • istream_iterator允許使用懶惰求值
    • ostream_iterator操作
  • 反向迭代器
    • reverse_iterator的base成員函數


前言

除了為每個容器定義的迭代器之外,標準庫在頭文件iterator中還定義了額外幾種迭代器。這些迭代器包括以下幾種。

  • 插入迭代器(insert iterator):這些迭代器被綁定到一個容器上,可用來向容器插入元素。
  • 流迭代器(stream iterator):這些迭代器被綁定到輸入或輸出流上,可用來遍歷所關聯的IO流。
  • 反向迭代器(reverse iterator):這些迭代器向后而不是向前移動。除了forward_list之外的標準庫容器都有反向迭代器。
  • 移動迭代器(move iterator):這些專用的迭代器不是拷貝其中的元素,而是移動它們。


插入迭代器


插入器有三種類型,差異在于元素插入的位置:

  • back_inserter創建一個使用push_back的迭代器。
  • front_inserter創建一個使用push_front的迭代器。
  • inserter創建一個使用insert的迭代器。此函數接受第二個參數,這個參數必須是一個指向給定容器的迭代器。元素將被插入到給定迭代器所表示的元素之前。

inserter

當調用inserter(c,iter)時,我們得到一個迭代器,接下來使用它時,會將元素插入到iter原來所指向的元素之前的位置。即,如果it是由inserter生成的迭代器,則下面這樣的賦值語句:

*it = val;

等價于:

it = c.insert(it, val); // it指向新加入的元素val ++it; // 遞增it使其指向原來的元素

front_inserter

一直向首元素位置添加元素,添加后指向新的首元素。

以以下實例區分inserter和front_inserter的區別:


back_inserter

向容器尾部不斷添加元素。

以unique_copy函數為實例來觀察back_inserter的作用:

值得注意的是,與unique一樣,unique_copy也要求在源容器中重復元素是相鄰存放的,因此容器如果無序且重復元素未相鄰存放,unique_copy會失敗,穩妥起見應該先對vector排序。

vector<int> vi = {2, 6, 7, 13, 15, 20, 22, 23, 25, 30};list<int> li;ostream& os(cout);int n = 10;while(n--){vi.push_back(n);}sort(vi.begin(), vi.end());for(auto i : vi){os << i << ends;}os << endl;unique_copy(vi.begin(), vi.end(), back_inserter(li));for(auto i : li){os << i << ends;}os << endl;

輸出結果:



iostream迭代器

雖然iostream類型不是容器,但是標準庫定義了可以用于這些IO類型對象的迭代器。


istream_iterator 讀取輸入流


流迭代器不支持遞減運算,因為不可能在一個流中反向移動。

istream_iterator使用>>來讀取流。因此,istream_iterator要讀取的類型必須定義了輸入運算符。

  • 當創建一個istream_iterator時,可以將它綁定到一個流
  • 默認初始化相當于創建一個可以當作尾后值使用的迭代器。


用istream_iterator從標準輸入讀取數據,存入一個vector:

istream_iterator可以用來構建容器:

istream_iterator<int> in_iter(cin); istream_iterator<int> eof; vector<int> vec(in_iter, eof);

本例中我們用一對表示元素范圍的迭代器來構造vec。這兩個迭代器是istream_iterator,這意味著元素范圍是通過從關聯的流中讀取數據獲得的。這個構造函數從cin中讀取數據,直至遇到文件尾或者遇到一個不是int的數據為止。從流中讀取的數據被用來構造vec。


istream_iterator允許使用懶惰求值

當我們將一個istream_iterator綁定到一個流時,標準庫并不保證迭代器立即從流讀取數據。 具體實現時可以推遲從流中讀取數據的時機——直到我們使用迭代器時才真正讀取。標準庫中的實現所保證的是,在我們第一次解引用迭代器之前,從流中讀取數據的操作已經完成了。 對于大多數程序來說,立即讀取還是推遲讀取沒什么差別。但是,如果我們創建了一個istream_iterator,沒有使用就銷毀了,或者我們正在從兩個不同的對象同步讀取同一個流,那么何時讀取可能就很重要了。



ostream_iterator操作

可以對任何具有輸出運算符(<<運算符)的類型定義ostream_iterator。

當創建一個ostream_iterator時,我們可以提供(可選的)第二參數,它是一個字符串,在輸出每個元素后都會打印此字符串。此字符串必須是一個C風格字符串(即,一個字符串字面常量或者一個指向以空字符結尾的字符數組的指針)。

與iostream_iterator不同的是:必須將ostream_iterator綁定到一個指定的流,不允許空的或表示尾后位置的ostream_iterator。

可以用ostream_iterator來輸出值的序列:

此程序將vec中的每個元素寫到cout,每個元素后加一個空格。每次向out_iter賦值時,寫操作就會被提交。

值得注意的是,當我們向out_iter賦值時,可以忽略解引用和遞增運算。即,循環可以重寫成下面的樣子:

istream_iterator<int> in_iter(cin); istream_iterator<int> eof; vector<int> vec(in_iter, eof); ostream_iterator<int> out_iter(cout, " "); for(auto i : vec){out_iter = i; } cout << endl;

運算符*和++實際上對ostream_iterator對象不做任何事情,因此忽略它們對我們的程序沒有任何影響。 但是,推薦第一種形式。在這種寫法中,流迭代器的使用與其他迭代器的使用保持一致。如果想將此循環改為操作其他迭代器類型,修改起來非常容易。而且,對于讀者來說,此循環的行為也更為清晰。

可以通過調用copy來打印vec中的元素,這比編寫循環更為簡單:

copy(vec.begin(), vec.end(), out_iter); cout << endl;

可以用unique_copy代替copy只打印不重復元素:



反向迭代器

反向迭代器就是在容器中從尾元素向首元素反向移動的迭代器。對于反向迭代器,遞增(以及遞減)操作的含義會顛倒過來。遞增一個反向迭代器(++it)會移動到前一個元素;遞減一個迭代器(- -it)會移動到下一個元素。


反向迭代器逆序打印vector<int>中的元素:

對照普通迭代器可以看出,rbegin指向尾元素,rend指向首元素前,遞增和遞減操作的含義會顛倒過來:反向迭代器的遞增操作會移動到前一個元素。

反向迭代器也有十分方便的時候,比如不加額外參數就可以使得元素降序排列:

reverse_iterator的base成員函數

base成員函數用來將反向迭代器轉換成其對應的普通迭代器(當然反過來也是可以的,普通迭代器轉換成對應的反向迭代器):

圖中的對象顯示了普通迭代器與反向迭代器之間的關系。例如,rcomma和rcomma.base()指向不同的元素,line.crbegin和line.cend()也是如此。這些不同保證了元素范圍無論是正向處理還是反向處理都是相同的。

從技術上講,普通迭代器與反向迭代器的關系反映了左閉合區間的特性。關鍵點在于[line.crbegin(),rcomma)和[rcomma.base(),line.cend())指向line中相同的元素范圍。為了實現這一點,rcomma和rcomma.base()必須生成相鄰位置而不是相同位置,crbegin()和cend()也是如此。


總結

以上是生活随笔為你收集整理的插入迭代器、流迭代器、反向迭代器、移动迭代器的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。