我有异常安全和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 –