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

C++ 我应该在代码中使用std::vector::at()吗,c++,optimization,vector,bounds,C++,Optimization,Vector,Bounds,我今天注意到,std::vector::at()比使用方括号访问值要慢得多。根据doc,at()更安全,因为它不允许我访问超出数组边界的值。但是,即使我使用at()访问越界值,我显然仍然会有一个错误,因此无论发生什么情况,我都需要避免这种情况 那么,有没有什么好的理由让任何人使用at()而不是[]?at()和操作符[]之间的区别在于at()通过抛出一个out\u of\u range异常,在请求的位置超出范围时发出信号。 因此,使用at()可以对错误状态做出反应。使用运算符[]访问索引外的向量将

我今天注意到,
std::vector::at()
比使用方括号访问值要慢得多。根据doc
,at()
更安全,因为它不允许我访问超出数组边界的值。但是,即使我使用
at()
访问越界值,我显然仍然会有一个错误,因此无论发生什么情况,我都需要避免这种情况


那么,有没有什么好的理由让任何人使用
at()
而不是
[]

at()
操作符[]
之间的区别在于
at()
通过抛出一个out\u of\u range异常,在请求的位置超出范围时发出信号。

因此,使用
at()
可以对错误状态做出反应。使用运算符[]访问索引外的向量将导致未定义的行为。

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

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


就我个人而言,我看不出有什么好的理由让
at()。您可能会设计一些示例,希望使用异常处理作为一种方便的方式来指导控制流,但任何此类用例都是非常有条件的。

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

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

at()引发超出范围异常,而[]不会

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


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

at
进行范围检查,但
操作符[]
不进行范围检查。例如,如果将-1传递给
at()
,将抛出
std::out\u of_range
。但是如果您对
操作符[]
执行相同的操作,它将崩溃或发生奇怪的事情


如果您完全确定索引正常,或者您想自己进行检查,请使用
操作符[]

是否在启用优化的情况下编译?不确定,我使用的是带有默认构建选项的QtCreator,并且在文档中看不到任何“优化”标志。可能使用调试进行编译是std::vector::at()的原因非常慢。@Rafal:好的一点-在没有异常的情况下,异常代码不应该对代码流造成太多干扰-您主要需要支付一次额外检查,以及调用站点上的一点代码膨胀(可能会妨碍缓存性能),但是通过优化,异常代码的影响应该相当小。运算符[]很可能会从vectors保留内存返回未定义的值。正确的说法是“访问越界索引会导致未定义的行为”。澄清了我的帖子。不过,应用程序很可能会崩溃。
operator[]
也可能格式化硬盘或订购比萨饼,我被告知。为UB可能发生的事情列出一个包含性的列表充其量是不可能的,最坏的情况是误导性的…+1对于Kerrek来说,比只有一个绑定检查一个没有更好的解释。+1同样,在调试模式下,一些实现在使用
操作符[]
时也会执行绑定检查,例如VC++(可能还有扩展的Dinkumware库)我不是下一个投票人(而且我认为答案不值得下一个投票),但考虑到[]的唯一优势是速度,如果速度在您编写的函数中基本不相关,我更喜欢使用at()。我们的代码设置方式是,我们记录从哪个模块引发的异常,因此使用at()它使我们或QA在全新的模块和功能中发现的愚蠢错误的故障排除变得更容易/更快。