可能STL迭代器方法抛出异常

时间:2011-10-26 12:18:08

标签: c++ exception stl

Destructors may not throw exceptions(因此stack unwinding可以在异常处理期间完成),并且必须释放分配给该对象的任何资源(因此没有资源泄漏)。包含多个其他对象(或分配了多个资源)的对象的设计可能会在STL容器中记录指向它们的指针。因此析构函数将使用以下与迭代器相关的方法:

  • begin()end()代表容器
  • operator++表示有效的迭代器
  • operator*operator->表示有效的迭代器

但是为了保证析构函数不会抛出异常并释放其资源,您需要依赖那些永远不会抛出异常的方法。

依赖那些从不抛出异常的方法是否安全?很难想象一个实际的实现会抛出异常,因为STL迭代器本质上是一个指针。但标准C ++ 是否需要这些方法是否永远不会抛出异常?我没有在C ++标准中找到明确的陈述。


编辑:当你想拥有a container of pointers to resources时,有趣的情况是C ++ 03。这样做有充分的理由;例如,如果您有多态资源。正如Björn Pollex在他的回答中指出的那样,如果你使用一个资源容器(例如std::list< Resource >)而不是指向资源的指针的容器,容器的析构函数将负责销毁(解除分配) )Resource对象为你。

4 个答案:

答案 0 :(得分:16)

  

operator ++用于有效的迭代器

C ++标准(我参考N3290草案)并没有给迭代器的增量运算符提供非保证。

例如,std::istreambuf_iterator::operator++在调用std::basic_streambuf::sbumpc时受到影响。 sbumpc可能会调用uflow,而{{1}}可能会引发异常。

答案 1 :(得分:6)

  

返回迭代器的复制构造函数或赋值运算符不会抛出异常

这是来自C ++ 03标准。我不认为标准比这更进一步。

顺便说一下。它是23.1.10

答案 2 :(得分:1)

  

因此析构函数将使用以下与迭代器相关的函数   方法

不,不会。该对象的析构函数只会调用容器的析构函数,这反过来会保证不会抛出异常。

如果正确使用RAII,您几乎不会遇到必须明确释放资源的情况。这可以通过容器存储shared_ptrunique_ptr或使用Boost.Pointer Container之类的东西来实现。

答案 3 :(得分:0)

根据http://www.tenouk.com/Module31.html这些操作(对于'*'和' - &gt;',它还取决于存储的类型)不是STL容器的抛出。