C++ 检查std::vector索引是否超出范围的最快方法是什么?

C++ 检查std::vector索引是否超出范围的最快方法是什么?,c++,stdvector,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 correc

通常,我想确保我在函数体的顶部有一次在边界内。 我这样做的不同方式是:

// 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 ..
}
//我不太喜欢它,因为它会在我不想的时候停止程序
断言(idx
idx < vec.size()

我假设你正在这个向量上循环。如果你正在为其编写代码的函数没有在循环中被调用或其他什么,那就不用担心了。根据编译器的向量实现,这两条语句都编译成相同的3或4条指令。如果函数是在循环中被调用的,请做两件事:使其内联e、 并取消检查。相反,在调用函数中对照边界检查索引


另外,别担心,因为还有其他一些东西是你的瓶颈。看看你的API调用、循环中虚拟函数的使用、浮点到整数转换、排序过程、线程同步……相信我,这不会有什么坏处。

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

如果可能正在使用未验证的输入,则应使用at()方法。如果索引超出范围,并且在所有其他情况下的行为类似于运算符[],则会引发异常。除非您显式捕获并补偿,否则该异常将导致应用程序退出(只有当这是一个有效的选项时,您才应该这样做,否则让应用程序退出(如果合适的话,可能会有一条错误消息)

就个人而言,我更喜欢使用exception而不是asserts()。

断言可以在编译器级别关闭(因此它们在生产代码中是无用的(只有在单元测试中测试代码才有效)),异常提供相同的功能(如果触发它们,则快速关闭应用程序(以及允许您记录信息的类似异常))。与断言不同,在适当的情况下可以捕获异常(尽管大多数情况下您只是想让它们终止应用程序))

我不认为你应该担心效率,而应该担心哪一个是正确的。我认为你担心太多了。这种事情不会导致性能的崩溃。无论如何,你可能想看看C++异常(谷歌IT)。A)过早优化是坏的。你没有理由在乎需要多长时间,因为这不是问题。B) 如果你真的想知道的话,每项测试都要做几千次,每次都要花多少时间。@Brian Roach我完全同意,如果你有一些像这样的测试,那真的没什么大不了的。但是,如果将数百万数据加载到一个数据库中,请考虑多次调用此检查database@karimjee:如果你这样做了数百万次,将数据加载到数据库中,这不会成为瓶颈。与数据库的通信将要大几个数量级,并导致更多的处理器挂起(因此,检查中的任何低效将有效地蒸发到零时间)。这就是为什么过早优化是危险的(在你计时之前,你根本不知道这是否是一个问题,因此最终会浪费时间优化一些永远不会影响总体时间的东西)。不过,这不是相同的测试。我想早点失败;此测试虽然正确,但可能没有那么方便。我想在开始时执行一次检查的全部目的是以后不必使用检查访问…
。at()
会产生运行时开销,即使您以前验证过用户输入<代码>断言
帮助您确保在开发时正确验证,并且在发布模式下不会花费任何费用。@Ayxan sure。但是,如果在生产中出现错误,assert不会保护您。如果存在未验证索引的可能性,则需要使用
at()
try {
    vec.at(idx) = stuff;
} catch (std::out_of_range& err) {
    // oh dear god
}