16

我今天注意到这std::vector::at()比使用方括号访问值要慢得多[]。根据文档.at()更安全,因为它不会让我访问超出数组范围的值。但是,即使我使用 访问超出范围的值at(),我显然仍然会遇到错误,因此无论如何我都需要避免这种情况。

那么有什么好的理由为什么有人会使用at()而不是[]

4

6 回答 6

22

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

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

就个人而言,我看不出有什么好的理由at()可以在发布代码中存活下来。您可能会设计一些示例,在这些示例中,您希望使用异常处理作为一种方便的方式来指导您的控制流,但是任何这样的用例都是非常有情景的。

于 2011-08-02T11:32:46.767 回答
11

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

于 2011-08-02T11:32:19.710 回答
4

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

如果您绝对确定索引正常,或者您想自己进行检查,请使用operator[].

于 2011-08-02T11:34:37.033 回答
1

at()返回具有索引的元素,i 如果索引超出范围则抛出范围错误异常i。所以我建议使用at()而不是[]因为如果超出范围会产生未定义的行为。如果你想在你的 proggy 使用中安全at():)。

于 2011-08-02T11:33:00.403 回答
1

at() 会引发 out_of_range 异常,而 [] 不会。

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

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

于 2011-08-02T11:34:33.937 回答
0

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

于 2011-08-02T11:34:33.807 回答