[英]STL iterator revalidation for end (past-the-end) iterator?
這更像是一個設計問題,即(在STL或其他地方)是否有像過去的迭代器“重新驗證”這樣的概念?
我的意思和用例:假設一個算法需要“尾隨”一個容器(如隊列)。 它遍歷容器直到到達end()
,然后暫停; 獨立於此,程序的另一部分將隊列中的更多項目排入隊列。 算法(EDIT)如何有效地告訴“有更多的項目已經入隊”,同時保持先前的過去的迭代器(稱之為tailIt
)? (這意味着它能夠檢查tailIt == container.end()
仍然存在,如果為false,則結束tailIt
現在有效並指向插入的第一個元素)。
請不要將這個問題視為“不,沒有” - 我正在尋求圍繞如何以慣用的方式設計一些邏輯的判斷,並且有很多選擇(事實上,所討論的迭代器是一只手- 我可以提供此屬性的構建數據結構 - 結束()重新驗證 - 但我想判斷它是否是一個好主意)。
編輯:明確我們有迭代器tailIt
和 container
的引用。 我正在嘗試做的一個簡單的解決方法是,還記得count
:=你處理了多少項,然后檢查是container.size() == count
仍然container.size() == count
,如果沒有,尋找container[count]
並繼續從那里處理。 這帶來了許多缺點(額外狀態,假設容器不從前面彈出(!),隨機訪問以進行有效搜索)。
不一般。 以下是您的想法的一些問題:
將所有這些放在一起很明顯,最終迭代器不能以這種方式使用,因為當前設計了迭代器接口。 迭代器引用范圍內的數據,而不是容器; 那么,它有理由說它們沒有關於容器的信息,如果容器導致范圍發生變化,那么迭代器就不會知道它可以要求找出它。
描述的邏輯是否可以創建? 當然! 但是使用不同的迭代器接口(以及來自容器的支持)。 您可以將容器包裝在您自己的類類型中以執行此操作。 但是,我建議不要制作看起來像標准迭代器的東西,但行為不同; 這將是非常令人困惑的。
相反,封裝容器並提供自己的包裝函數,可以直接執行您認為需要的任何后置入操作。 您不應該需要觀察最終迭代器的狀態來實現您的目標。
在std :: queue的情況下,沒有(heh)。 不是因為一旦推送了某個隊列,隊列的迭代器就會失效,而是因為隊列根本沒有任何迭代器。
對於其他迭代器類型,它們中的大多數(或其中任何一個)都不需要對容器持有者的引用(管理對象包含有關基礎數據的所有信息)。 這是效率優於靈活性的權衡。 (我快速檢查了gcc的std :: vector :: iterator的實現)
可以為迭代器類型編寫一個實現,該實現在其生命周期內保持對持有者的引用,這樣迭代器就不必被無效! (除非持有人是std :: move'd)
現在提出我的專業意見 ,我不介意在迭代期間迭代器通常無效的情況下看到safe_iterator / flex_iterator。
可能的用戶界面:
for (auto v : make_flex_iterator(my_vector)) {
if (some_outside_condition()) {
// Normally the vector would be invalidated at this point
// (only if resized, but you should always assume a resize)
my_vector.push_back("hello world!");
}
}
字面上重新驗證迭代器可能太復雜而無法構建它的用例(我不知道從哪里開始),但設計一個永遠無效的迭代器是非常簡單的,只需要與for (size_t i = 0; i < c.size(); i++);
環。
但話雖如此,我無法向您保證編譯器將如何利用這些迭代器進行優化,例如展開循環。 我認為它仍然會做得很好。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.