3

我试图确定以下代码中是否需要 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。我是不是过于偏执了,还是真的是这样?

4

3 回答 3

4

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

  • erase()pop_back()pop_front()函数抛出异常。
  • 返回的迭代器的任何复制构造函数或赋值运算符都不会引发异常。

如果你真的很偏执,那么你应该考虑begin()and的可能性end(),甚至迭代器增量,抛出;但是他们不需要在标准容器的任何理智实现中做任何复杂的事情。

于 2012-04-19T11:15:30.953 回答
2

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

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

我假设您的恐惧是push_back()在您的示例案例中引发,如果不是,那么是的,您是偏执狂。begin()尽管如此,它是一个实现细节在实践中,如果您只是获取迭代器( , ),几乎没有一个实现会尝试分配end()

于 2012-04-19T10:59:56.797 回答
0

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

就容器本身而言,我不会担心begin和抛出,但还有另一个麻烦点:迭代器实现。end如果迭代器是类类型,那么理论上此类实例的构造(或分配)很可能会抛出。因此,虽然我认为任何随机选择的标准库实现都不可能抛出,但您不能真正排除它。

于 2012-04-19T11:11:52.330 回答