std::vector::at()
访问值要比使用方括号[]
慢得多。根据文档,.at()
更安全,因为它不允许我访问数组范围之外的值。然而,即使我使用at()
访问越界的值,我仍然会遇到错误,所以无论如何我都需要避免这种情况。那么是否有什么好的理由让任何人使用
at()
而不是[]
呢?std::vector::at()
访问值要比使用方括号[]
慢得多。根据文档,.at()
更安全,因为它不允许我访问数组范围之外的值。然而,即使我使用at()
访问越界的值,我仍然会遇到错误,所以无论如何我都需要避免这种情况。at()
而不是[]
呢?如果你认为索引不在你的控制之内,或者控制流程特别复杂且你要跟踪错误,那么你可能想在调试阶段使用 at()
,但永远不要在循环内或任何你知道索引是安全的情况下使用。
即使在其他情况下,你也应该预验证索引(例如,如果它是用户输入),或者如果你只是从一个复杂的算法中获取值,则使用 assert
并修复其中的错误。[编辑] 或者,如果你正在编写非常复杂的算法,并且不确定所有索引是否始终有效,那么你可以在该算法内部使用 at()
,并将调用放入 try 块中——但即使在这种情况下,最好还是采用断言方式。
个人而言,我看不出任何 at()
能够在发布代码中生存的好理由。你可能可以构造一些例子,想要使用异常处理作为方便的方式来指导你的控制流程,但是这样的用例都非常具体。
operator[]
时也会执行边界检查,例如 VC++(可能还包括 Dinkumware 库)。 - Praetorianat()
和 operator[]
的区别在于,at()
在请求的位置超出范围时通过抛出 out_of_range 异常来进行信号传递。
因此,通过使用 at()
您可以对错误状态做出反应。如果使用 operator[] 访问向量超出索引,则会导致未定义行为。
at
进行范围检查,但operator[]
不会。例如,如果你将-1传递给at()
,则会抛出一个std::out_of_range
异常。但是,如果你对operator[]
做同样的事情,它会崩溃或产生奇怪的结果。
如果你绝对确定索引没有问题或者想自己进行检查,请使用operator[]
。
at()
返回索引为 i
的元素,如果索引 i
超出范围,则抛出范围错误异常。因此,我建议使用 at()
而不是 []
,因为后者会产生未定义的行为,如果超出范围。如果您想在程序中保证安全,请使用 at()
:)
at() 会抛出 out_of_range 异常,而 [] 不会。
因此,如果您尝试访问超出范围的内容,[] 可能会立即使应用程序崩溃,而 at() 则可以在运行时处理错误。
如果这对您很重要(通常情况下不需要,因为访问超出范围的内容自动意味着代码语义不按预期工作),则应使用 at()。
vector::at()
将始终在尝试访问越界索引时抛出异常。vector::operator[]
可能会返回未定义的值或抛出访问冲突异常(或崩溃)。operator[]
还可能会格式化您的硬盘或订购披萨。列出由 UB 引起的可能事件的包容性清单,最好是不可能的,最坏的情况是具有误导性的... - Kerrek SB