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

发布于 2024-12-04 03:49:05 字数 346 浏览 0 评论 0原文

通常,我想确保一旦到达函数体的顶部,我就处于边界内。 我执行此操作的不同方法是:

// 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 ..
}

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

Often I want to make sure I am in bounds once at the top of my function body.
The different ways I do this are:

// 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 ..
}

Between the second and third method (and maybe others), which is more efficient?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

零度℉ 2024-12-11 03:49:06

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

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

就我个人而言,我更喜欢使用异常而不是断言()。
断言可以在编译器级别关闭(因此它们在生产代码中毫无用处(仅适用于测试代码在单元测试中是否有效)),异常提供相同的功能(如果触发,则快速关闭应用程序(并且就像例外一样,它们允许您记录信息))。与断言不同的是,如果适当的话,可以捕获异常(尽管大多数情况下您只想让它们终止应用程序))。

Most of the time you are not going to check. Because you have already validated the user input at the point where it enters the program thus you should not need to check anywhere else.

If there is any possibility that unvalidated input is being used then you should be using the method at(). This will throw an exception if the index is out of bounds and behave like operator[] in all other situations. The exception will cause the application to quit unless you explicitly catch and compensate (which you should only do if that is a valid option otherwise let the application exit (maybe with an error message if appropriate)).

Personally I much prefer to use exception instead of asserts().
Asserts can be turned off at the compiler level (so they are useless in production code (only good for testing the code is valid in unit tests)), exceptions provide the same functionality (quick shut down of the application if they are triggered (and like exceptions they allow you to log info)). Unlike asserts exceptions can be caught if appropriate (though mostly you just want to let them kill the application)).

蝶…霜飞 2024-12-11 03:49:06

我假设你正在循环这个向量。如果您为其编写此代码的函数没有在循环或其他内容中被调用,则不必担心。两个语句都编译为相同的 3 或 4 条指令,具体取决于编译器的向量实现。如果在循环中调用该函数,请执行两件事:使其内联,并取消检查。相反,根据调用函数中的边界检查索引。

另外,不要担心它,因为其他事情是你的瓶颈。看看你的 API 调用、循环中虚拟函数的使用、float 到 int 转换、排序过程、线程同步......相信我,这不会有什么坏处。

I assume you're looping over this vector. If the function for which you're writing this code isn't being called in a loop or something, just don't worry about it. Both statements compile to the same 3 or 4 instructions, depending on your compiler's vector implementation. If the function IS being called in a loop, do two things: make it inline, and get rid of the check. Instead, check the index against the boundary in the calling function.

Also, just don't worry about it, because something else is your bottleneck. Look at your API calls, use of virtual functions in loops, float to int casts, sort procedures, thread synchronizations... trust me, this isn't going to hurt.

木格 2024-12-11 03:49:05

只需使用

idx < vec.size()

即可完成。在这个问题上多花一分钟不会让你的应用程序任何变得更快。

另外,请考虑检查访问:

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

Just use

idx < vec.size()

and be done with it. You're not going to make your application any faster by spending another minute on this issue.

Also, consider checked access:

try {
    vec.at(idx) = stuff;
} catch (std::out_of_range& err) {
    // oh dear god
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文