使用std :: out_of_range是不是很糟糕?

时间:2017-07-21 06:52:02

标签: c++ arrays exception try-catch

在我的项目中,我有很多这样的情况:

constexpr size_t element_count = 42;
std::array<bool, element_count> elements;

for(size_t i = 0; i < element_count; ++i){
    if(i > 0 && elements[i - 1]){/*do something*/}
    else{/*do something else*/}
    if(i < element_count - 1 && elements[i + 1]){/*do something*/}
    else{/*do something else*/}
}

不检查i > 0i < element_count,我会得到未定义的行为。如果我使用std::array::at代替operator[],我可以获得std::out_of_range例外。我想知道是否有任何问题只是依赖这样的例外:

for(size_t i = 0; i < element_count; ++i){
    try{
        if(elements.at(i - 1)){/*do something*/}
    }
    catch(const std::out_of_range& e){/*do something else*/}
    try{
        if(elements.at(i + 1)){/*do something*/}
    }
    catch(const std::out_of_range& e){/*do something else*/}
}

在这个例子中它有更多的代码,但在我的真实项目中它会减少代码量,因为我使用了大量的多维数组并且检查了多个维度的边界。

1 个答案:

答案 0 :(得分:0)

从某种意义上讲它没有问题,但它就是这样的。使用异常for basic flow control(这是你在这里做的)通常是frowned upon,有理由,我不认为我在循环中看到过这样的事情:

  • 使得对代码的阅读和推理更加困难,也因为它意外地使用了流控制的异常(而不是错误处理,这就是它在C ++中的意思)
  • 更难阅读通常也意味着更难写,并且更难发现错误
  • 你实际上已经犯了一个错误,或者至少引入了行为改变:i&gt; 0&amp;&amp;元素[i - 1]评估为false不会导致“别的东西”再被调用
  • 如果导致代码不太可读或代码更差,则减少代码量不再是一个好目标
  • 可能性能较差

现在看到实际代码会很有趣,但我怀疑它可能没有任何边界检查,例如通过使循环从1开始而不是0开始。或者,如果这是一个recurrnig模式,您可以编写辅助函数(或使用现有的on)进行迭代,并在一次迭代中访问多个元素。这将减少代码量,这实际上是值得的。