我有異常安全和STL容器/迭代器的問題。C++迭代器異常安全
我承擔了一些原因,簡單的容器的迭代器上執行算術運算時
std::vector<POD Type>
不拋出異常(或DEREF。它)只要你留在區間[開始(), 結束())。我試圖用標準來看(使用N3337),但是我發現沒有給出這樣的保證(但也許我錯過了一些東西!)。另請參閱:May STL iterator methods throw an exception
到現在爲止,我寫了一些相當普遍的代碼,考慮到即使對於具有合理元素類型的簡單容器也沒有提供不保證的保證。
例如像下面可能仍然拋出一個異常(其中c是一個std :: vector的實例):
for(... i = c.begin(); i != c.end(); ++i) { /* do something here - guaranteed to not throw. */ }
但這招在不同的性病庫,因爲你有例外安全和程序的穩定性問題據我所知,瞭解迭代器操作的實現。
例如,使用Boost.Graph的鄰接列表的clear()函數(並且Boost中還有更多這樣的例子),假設容器m_vertices是std :: vector之類的std序列容器。
inline void clear() {
for (typename StoredVertexList::iterator i = m_vertices.begin(); // begin() and copy assignement does not throw (according to the STD)
i != m_vertices.end(); ++i) // ++i and operator !=() might throw
delete (stored_vertex*)*i; // *i might throw
m_vertices.clear(); // will not throw (nothrow per Definition of the STD)
m_edges.clear(); // same
}
此功能應保證不丟,因爲這就是所謂的adjacency_list <的析構函數...>,這將是合理的假設,沒有明確的()函數拋出,即使我沒有找到Boost.Graph文檔中的任何異常安全保證。
我希望你能揭示一下這個異常安全問題,並告訴我我在這裏失去了什麼。特別是對於什麼樣的迭代器算術運算和解引用實際上不是拋出以及定義了哪些保證。
謝謝!
從C++ STD紙N3337
23.2.1:10)
除非另有規定(參見23.2.4.1,23.2.5.1,23.3.3.4和23.3.6.5)所有的容器類型定義在此 子句中滿足以下附加要求:
- 如果insert()或emplace()函數在插入單個元素時引發異常,那麼 函數不起作用。
- 如果push_back()或push_front()函數引發異常,則該函數不起作用。 (),clear(),pop_back()或pop_front()函數拋出異常。
- 返回的迭代器的拷貝構造函數或賦值操作符拋出異常。
- no swap()函數拋出異常。
- 沒有swap()函數使任何引用,指針或迭代器都指向正在交換的容器的元素。
[注意:end()迭代器不引用任何元素,因此可能會使 無效。 - 注意]
不支持在迭代容器時調用container.erase()。如果你這樣做,一個實現可能會簡單地崩潰或者可能拋出一個異常。 –
brian beuning:我不確定你在說什麼 - 這與我的問題有關嗎?但是在迭代像STD序列容器之類的容器時調用擦除操作完全有效! – livingissuicide
查看http://stackoverflow.com/questions/6438086/iterator-invalidation-rules –