C 標頭檔案系列 iterator

2021-07-26 14:56:50 字數 2926 閱讀 7665

該標頭檔案圍繞迭代器展開,定義了一系列與迭代器有關的概念,但最最最重要的一點就是----它和其它容器一起實現了c++容器的iterator設計模式

上述文字摘自c++14標準草案,簡而言之,迭代器就是對指標的一層封裝,提供了統一的介面

使用迭代器有很多好處:

詳細請見設計模式。

迭代器主要有5類([iterator-class]代指該類迭代器支援的操作集):

這裡有兩點需要特別說明:

不難看出,這幾類迭代器有如下關係:

因為迭代器實際上是指標的抽象,很多功能概念都是從指標身上「扒」下來的,所以它的語義跟指標是一致的

這意味著什麼呢? 這意味著可以傳入指標作為迭代器, 因為指標上的操作集(遞增、遞減、算數運算等)是迭代器的超集,模版定義對迭代器所做出的操作要求放在指標上完全適用。

這在操縱內建陣列的時候,可以省去不少麻煩(不用再去敲多餘的**來生成iterators):

int numbers = ;

std::find(numbers, numbers + 4, 2);

標準庫提供了以下4個方面的設施來幫助使用者使用iterator。

「traits」是特性的意思,所以「iterator_traits」是迭代器特性的意思。 從**角度看,這裡的traits就是types,因為這個類只包含了五個型別定義:

因為algorithm在c++是單獨的一塊,是iterator將容器與演算法溝通在一起。 也就是說,標準庫的演算法只是通過迭代器來進行資料操作。 必然而然的,一些操作需要有對應的型別: 1) 例如,應用distance庫函式計算迭代器的距離,應該返回「距離」型別的值。 2) 例如,獲取迭代器指向的物件,應該返回「物件值」型別的物件。 等等...

所以,標準庫的演算法需要我們定義這些型別,好讓它在應用演算法的時候使用正確的型別。

需要注意的是,當迭代器為output iterators時,上面的4個型別可能被定義為void(可能對於output iterator來說,這四個型別都沒有多大意義,它支援的操作非常有限)。

上面這個iterator_traits類取自某個庫的iterator實現,可以看到,預設的iterator_traits模版內的型別定義都取自迭代器中相應的型別,即_iter迭代器類。 所以我們在定義自己的迭代器的時候,如果定義了這些類,就不用再顯示例項化iterator_traits模版了,它能自動提取出這些型別。

這時候就輪到我們的iterator類來大顯身手啦! 使用者只要繼承這個base class並指定兩個引數,就可以獲得剩餘的三個型別定義,因為它的定義是這樣的:

對應迭代器類別,這裡也有5類標籤(tag),名稱為***_tag,***對應迭代器名稱。

這個標籤的作用主要是實現標籤派發功能,提供迭代器型別資訊,從而讓c++庫演算法可以選擇合適的、高效的操作來完成演算法(可參見下一小節)。

標頭檔案還提供了一些方便的操縱迭代器的函式供使用者使用:

對於不同型別的迭代器,上述四個函式採用不同的方法進行計算,例如:

標準庫包含了三種迭代器介面卡:

reverse iterator:這種迭代器對元素進行反向迭代。 注意,當從某個迭代器構造出reverse iterator時,新的迭代器不再指向先前的元素,而是指向前乙個元素(按舊迭代器的順序),因為end iterator逆轉過來才是begin iterator。

insert iterator:通過迭代器進行元素的插入時,操作略有不同。 指標通常是指向已有的記憶體,因此迭代器一般也只是對指向位址的元素進行賦值;而插入元素是需要先分配記憶體,再賦值。 為了能讓使用者像使用一般迭代器那樣進行元素的插入,標準庫提供了3種插入迭代器

move iterator:移動迭代器會將內部的迭代器的操作返回值全部轉換成右值(rvalue)。

這些都是全域性模版函式,利用型別推導幫助使用者構造上述的三種迭代器介面卡。

輸入輸出一直是語言非常重要的部分,對於c++迭代器來說,操縱流(stream)中資料的輸入輸出的重要性毋庸置疑。 stream iterator則是針對stream的一套迭代器,包括istream,ostream,istreambuf 和 ostreambuf。

以下兩種是input iterator:

以下兩種是output iterator:

C 標頭檔案系列 iterator

該標頭檔案圍繞迭代器展開,定義了一系列與迭代器有關的概念,但最最最重要的一點就是 它和其它容器一起實現了c 容器的iterator設計模式。上述文字摘自c 14標準草案,簡而言之,迭代器就是對指標的一層封裝,提供了統一的介面。使用迭代器有很多好處 詳細請見設計模式。迭代器主要有5類 iterator...

C 標頭檔案系列 array

注意,該標頭檔案僅在c 11中標準才開始出現。與語言內建的陣列一樣,array類模版支援幾乎所有內建陣列包含的特性 那既然與內建陣列一樣,為什麼還要定義這樣乙個模版呢?c 委員會是想造輪子嗎 當然不是!array模版類實際上是內建陣列的聚合,外加一層封裝。正是由於這層介面,才使得陣列能與stl接軌,...

C 標頭檔案系列 system error

報告源於作業系統或低層程式介面的錯誤。更進一步說,system error 提供了用於報告該方面錯誤的異常機制,是對的擴充套件。物以類聚,功能也以 類 分。剛看到這個標頭檔案的內容,我也有點懵逼,讓我們先理清類與類之間的關係 雖然這幾個類之間存在非常複雜的轉換構造關係 實際上error condit...