我应该在代码中使用std::vector::at()吗

Should I use std::vector::at() in my code

本文关键字:vector at std 代码 我应该      更新时间:2023-10-16

我今天注意到,std::vector::at()访问方括号[]的值要慢得多。根据文档,.at()更安全,因为它不允许我访问超出数组界限的值。然而,即使我使用at()访问越界值,我显然仍然会有一个错误,所以无论怎样,这都是我需要避免的。

那么,为什么有人会使用at()而不是[]呢?

如果您有理由相信索引不在您的控制范围内,或者如果控制流特别复杂并且您正在跟踪错误,那么您可能希望在调试阶段使用at(),但不要在循环内或任何您知道索引是安全的情况下使用。

即使在其他情况下,您也应该预先验证索引(例如,如果它是用户输入(,或者如果您只是从复杂的算法中获得值,请使用assert并修复错误(如果有(。[Edit.]或者,如果您正在编写一个非常复杂的算法,并且您不确定所有索引始终有效,您可以在该算法中使用at(),并将调用放入try块中——但即使在这里,也最好是冒犯性的,并与断言一起使用。[/]

就我个人而言,我看不出at()能够存活到发布代码中有什么好的理由。您可以设计一些示例,将异常处理作为指导控制流的一种方便方式,但任何此类用例都是非常情境化的。

at()operator[]之间的区别在于,at()通过抛出out_of_range异常来发出请求位置是否超出范围的信号
所以使用at(),您可以对错误状态做出反应。使用运算符[]访问索引外的向量将导致未定义的行为。

at执行范围检查,但operator[]不执行。例如,如果将-1传递给at(),则会抛出一个std::out_of_range。但如果你对operator[]做同样的事情,它就会崩溃或发生奇怪的事情。

如果您绝对确定索引是可以的,或者您想自己进行检查,请使用operator[]

at((抛出out_of_range异常,[]没有。

因此,如果您试图访问超出范围的内容,[]可能会使您的应用程序立即崩溃,但at((将使您能够在运行时处理错误。

如果这对你来说是必要的(通常情况下,这不是因为自动访问超出范围的内容意味着你的代码的语义不能正常工作(,你应该使用at((。

at()返回索引为i的元素,如果索引i超出范围,则抛出范围错误异常。所以我建议使用at()而不是[],因为如果超出范围,它会产生未定义的行为。如果您希望您的项目安全,请使用at():(。

假设您不使用异常作为某种信号系统,不同之处在于,当您试图访问越界索引时,vector::at()将始终抛出异常。vector::operator[]可能返回一个未定义的值,或者引发访问冲突异常(或崩溃(。