我今天注意到std::vector::at()
明显慢于使用方括号[]
访问值。根据文档.at()
更安全,因为它不会让我访问超出数组范围的值。但是,即使我使用at()
访问超出范围的值,我显然仍会有错误,所以无论如何我都需要避免这种情况。
那么为什么有人会使用at()
代替[]
有什么理由呢?
答案 0 :(得分:20)
如果您有理由相信索引不在您的控制之下,或者控制流程特别复杂并且您正在跟踪错误,那么您可能希望在调试阶段使用at()
,但是从不在循环内或任何你知道索引是安全的情况。
即使在其他情况下,您也应该预先验证索引(例如,如果是用户输入),或者如果您只是从复杂算法中获取值,请使用assert
并修复错误(如果有)。 [编辑。]或者如果您正在编写一个非常复杂的算法并且您不确定所有索引是否始终有效,您可以在该算法中使用at()
并拨打电话进入试块 - 但即使在这里,最好是冒犯并使用断言。[/]
就个人而言,我看不出at()
存在于发布代码中的任何充分理由。你可以设想一些你希望使用异常处理作为指导控制流的方便方法的例子,但任何这样的用例都是非常情境化的。
答案 1 :(得分:9)
at()
与operator[]
之间的区别在于at()
通过抛出out_of_range异常,如果请求的位置超出范围,则表示at()
。
因此,使用{{1}},您可以对错误状态做出反应。使用operator []从索引中访问向量将导致未定义的行为。
答案 2 :(得分:3)
at
会进行范围检查,但operator[]
没有。例如,如果将-1传递给at()
,则会抛出std::out_of_range
。但如果你对operator[]
做同样的事情,它会崩溃或发生奇怪的事情。
如果您完全确定索引是正常的,或者您想自己进行检查,请使用operator[]
。
答案 3 :(得分:1)
at()
返回索引为i
的元素,如果索引i
超出范围,则抛出范围错误异常。所以我建议使用at()
而不是[]
,因为如果超出范围会产生未定义的行为。如果你想在你的程序中使用安全at()
:)。
答案 4 :(得分:1)
假设您没有将异常用作某种信号系统,区别在于当您尝试访问超出范围的索引时,vector::at()
将始终抛出异常。
vector::operator[]
可能返回未定义的值或抛出访问冲突异常(或崩溃)。
答案 5 :(得分:1)
at()抛出一个out_of_range异常,[]没有。
因此,如果您尝试访问超出范围的某些内容,[]可能会立即使您的应用程序崩溃,at()将使您能够在运行时处理错误。
如果这对你来说是必要的(通常不会因为访问范围超出范围意味着你的代码的语义不能正常工作),你应该使用at()。 / p>