检查std :: vector索引是否超出界限的最快方法是什么?

时间:2011-09-12 23:22:19

标签: c++ stdvector

我经常想确保我在函数体的顶部处于界限之内。 我这样做的不同方式是:

// I don't like this much as it stops the program when I may not want to
assert( idx < v.size() );

if( !(idx < v.size()) )
{
    // take corrective action ...
}

if( v.size() <= idx )
{
    // take corrective action ..
}

在第二种和第三种方法(以及其他方法)之间,哪种更有效?

3 个答案:

答案 0 :(得分:4)

只需使用

idx < vec.size()

并完成它。在这个问题上花一分钟时间,你不会更快地使你的应用任何

另外,请考虑已检查的访问权限:

try {
    vec.at(idx) = stuff;
} catch (std::out_of_range& err) {
    // oh dear god
}

答案 1 :(得分:4)

大多数时候你不打算检查。 因为您已经在进入程序时验证了用户输入,因此您无需在其他任何地方进行检查。

如果有可能使用未经验证的输入,那么您应该使用()处的方法。如果索引超出范围,并且在所有其他情况下的行为类似于operator [],则会抛出异常。该异常将导致应用程序退出,除非您明确地捕获和补偿(只有在有效选项时才应该这样做,否则让应用程序退出(如果合适,可能会带有错误消息)。)

我个人更喜欢使用exception而不是asserts() 断言可以在编译器级别关闭(因此它们在生产代码中无用(仅适用于测试代码在单元测试中有效)),异常提供相同的功能(如果触发应用程序,则快速关闭应用程序(以及像异常他们允许你记录信息))。与断言不同,如果合适,可以捕获异常(尽管大多数情况下你只是想让它们杀死应用程序)。)

答案 2 :(得分:0)

我假设你正在循环这个向量。如果您正在编写此代码的函数未在循环或其他内容中调用,请不要担心它。两个语句都编译为相同的3或4条指令,具体取决于编译器的向量实现。如果在循环中调用函数IS,请执行以下两项操作:使其内联,并取消检查。相反,检查调用函数中边界的索引。

另外,不要担心,因为别的东西是你的瓶颈。看看你的API调用,在循环中使用虚函数,浮动到int强制转换,排序过程,线程同步......相信我,这不会受到伤害。