目前為止,提供的 fbl::
有許多用途範例。
疊代器fbl::
中的疊代器使用的 API 與
std::
容器,希望您會對這些內容感到熟悉。沒錯,
但能花點時間說明
除了支援 fbl::
疊代器外,也支援
std::
疊代器。
iterator
和const_iterator
和 std::
疊代器一樣,fbl::
疊代器提供兩種變種版本,也就是一個非常數的
和常數版本begin()
或 find()
等作業會傳回
以下情況使用簡易疊代器:
非 const
,否則為 const_iterator
。已執行解除參照作業
在 const_iterators
上,請授予 const T&
,因此 const
可存取
基礎物件
begin()
/end()
和 std::
一樣,容器上的 begin()
方法會將疊代器傳回
容器中第一個元素,而 end()
則會將疊代器傳回
元素的第一個元素開頭和結尾
在 const
參照上呼叫時,會自動傳回 const_iterator
但由於應用程式在容器載入時
可能會使用 cbegin()
/cend()
const_iterator
是明確使用
都會在 Docker 容器中執行
疊代器比較和預設初始化疊代器與 end()
的比較
和 std::
一樣,所有 fbl:疊代器支援使用 ==
測試相等性
和 !=
運算子。與 std::
不同,所有疊代器皆無法隨機存取
不支援疊代器語意和 >
、>=
、<
和 <=
運算子
適用於任何 fbl::
容器iterator 類型。
此外,預設的初始化之間有些微差異
對容器 end()
方法的呼叫傳回的疊代器和疊代器。
從語意的角度來看,它們都相同。預設初始化的疊代器和
end()
的值無效,因此兩者的比較會傳回 true
。
然而,兩個執行個體包含的位元不同。請一律使用
比較運算子來測試兩個疊代器之間的相等性。
fbl::DoublyLinkedList<Obj*> the_list;
fbl::DoublyLinkedList<Obj*>::iterator default_init;
auto end_init = the_list.end();
if (default_init == end_init) { } // This comparison is true
if (!memcmp(&default_init, &end_init, sizeof(end_init))) { } // This is not.
疊代器進展
所有疊代器都支援 ++
運算子的前和後後形式。
前置字串表單會將疊代器移至序列中的下一個元素
會傳回疊代器副本,指向下一個元素。修正後
表單在傳回時,會將疊代器移至序列中的下一個元素
預先進階疊代器的副本
// Assuming that the list starts containing objects with values
// "5 7 9", in that order.
fbl::DoublyLinkedList<Obj*> the_list;
auto iter = the_list.begin(); // iter points to "5".
auto second = iter++; // iter points to "7", but second points to "5"
auto third = ++iter; // iter points to "9", and so does third
++iter; // iter is now equal to the_list.end()
DoublyLinkedList
的疊代器、HashTable
具有雙連結清單值區的疊代器,
WAVLTree
都支援透過 --
運算子進行雙向疊代
。SinglyLinkedList
和 HashTable
,其中包含
安全連結的清單值區不會。
將疊代器移至容器結尾後,就會產生 container.end()
。
嘗試進一步發展是合法性,但並不會改變
iterator。備份目前設為下列方向的雙向疊代器
使用 --
運算子的 container.end()
會產生疊代器,
至清單的最後一個元素,但備份已產生的疊代器
。而是改為在++
--
初始化的預設值會讓疊代器處於預設的初始化狀態。
最後,備份值等於 container.begin()
的疊代器會
產生值等於 container.end()
的疊代器。隨後
--
的應用程式會按反向順序瀏覽元素,從
與最後一個元素
將疊代器取消參照
fbl::
容器中的元素一律為物件,因此一律支援
->
運算子和一元 *
運算子。兩者都會產生
T&
或 const T&
(->
隨後會存取成員),
iterator 是 const_iterator
或不可能的值。
試圖延遲無效的疊代器是非法行為,
視事件的性質而定,觸發 ZX_DEBUG_ASSERT
或未定義的行為
建構過程
使用 container::make_iterator(),透過物件建立疊代器
容器具有乾擾性,因此可以建立 容器疊代器舉例來說 會由索引鍵排序的物件樹狀結構、接受物件並傳回 或是對該物件的參照,或是說 例如:
using ObjectTree = fbl::WAVLTree<uint64_t, fbl::RefPtr<Object>>;
fbl::RefPtr<Object> FetchPrior(ObjectTree& tree, Object& obj) {
ZX_DEBUG_ASSERT(obj.InContainer());
auto iter = tree.make_iterator(obj);
return (--iter).IsValid() ? iter.CopyPointer() : nullptr;
}
iterator::IsValid()
系統可能會使用 IsValid
測試所有 fbl::
疊代器執行個體是否有效
方法。在這個步驟中測試疊代器是否有效
等於測試 iter != container.end()
,但 IsValid
方法可能會產生稍有效率的程式碼,但實際情況取決於
以及編譯器在實作中的
容器的 end()
方法
iterator::CopyPointer()
最後,fbl::
疊代器提供稱為 CopyPointer
的方法,可以
來產生容器所用指標類型的副本適用對象
原始指標的容器,這也很簡單它只是物件的 T*
副本
指向物件的指標。事實上,iter.CopyPointer() == &(*iter)
應一律
對原始指標的值為 true
對於具有專屬語意的代管指標,CopyPointer
概不法律規定。正在嘗試
對使用 std::unique_ptr
追蹤的物件容器呼叫 CopyPointer
會產生錯誤
最後,當 CopyPointer
針對容器容器的疊代器執行時
可複製的代管指標,系統會使用
指標類型的複製建構函式。也就是說,它會產生一個
物件的代管參照。
嘗試對無效疊代器呼叫 CopyPointer
至可複製的指標
類型會產生 nullptr