任何C ++ 98标准容器操作都可以抛出std :: bad_alloc吗?

时间:2012-04-19 10:58:08

标签: c++ stl

我试图找出以下代码中是否需要try catch:

std::vector<int> values;
// ignore that this can throw std::bad_alloc
values.push_back(1);
try {
    for (std::vector<int>::iterator iter = values.begin();
         iter != values.end(); ++iter) {
         ++(*iter);
    }
} catch (const std::bad_alloc&) { 
    // Is this needed?
}

通过C ++ 1998标准,我能找到的唯一提示是第23.1节“容器要求”第8点,其中包含句子:

  

此参数的副本用于在每个容器对象的生命周期内由这些构造函数和所有成员函数执行的任何内存分配。

我对此的解释是容器中的任何成员函数都可以调用分配器,因此任何成员函数都可以抛出std :: bad_alloc。我是否过于偏执或者情况确实如此?

3 个答案:

答案 0 :(得分:4)

如果你继续阅读,你会发现23.1 / 10,它给出了容器关于何时可以抛出异常的要求,特别是:

  • 没有erase()pop_back()pop_front()函数会抛出异常。
  • 没有复制构造函数或返回迭代器的赋值运算符会抛出异常。

如果你真的是偏执狂,那么你应该考虑begin()end()的可能性,甚至是迭代器增量,投掷;但是他们没有必要在任何合理的标准容器实现中做任何复杂的事情。

答案 1 :(得分:2)

理论上是,任何标准库容器成员函数都可以抛出bad_alloc

大多数标准容器本身不会抛出除(std::vector::at())之外的任何异常,但它们可能会因内存分配失败或用户定义操作异常而抛出异常。

我认为你的恐惧是push_back()抛出你的例子,如果不是,那么是的你是偏执狂。尽管如此,它是一个实现细节在实践中,如果您只是获取迭代器(begin()end()),几乎所有的实现都不会尝试分配。

答案 2 :(得分:0)

我没有在标准中找到更具体的内容,因此在没有证据的情况下,我们必须得出结论,从技术上讲,任何容器方法都可以抛出bad_alloc

就容器本身而言,我不担心beginend抛出,但还有另一个令人不安的问题:迭代器实现。如果迭代器是类类型,那么从理论上讲,这种实例的构造(或赋值)很可能会抛出。因此,虽然我认为任何随机选择的标准库实现都不可能抛出,但你不能真正排除它。