.at() 应该在 std::vector 或 std::array 中的 [] 上使用吗?

Should .at() be used over [] in std::vector or std::array?

本文关键字:std 中的 at vector array      更新时间:2023-10-16

这与这篇在std::vector中谈论.at()与[]的帖子有关。我只想问一下.at()是否应该在括号运算符上使用?以以下代码为例:

#include <vector>
#include <iostream>
void print(const std::vector<int> &v)
{
for(int i = 0; i < v.size(); ++i)
{
std::cout << v.at(i) << " ";
}
std::cout << std::endl;
}
int main()
{
std::vector<int> test = {1,2,3,4};
print(test);
}

我不会以这种方式打印矢量,我会使用for(const auto &e : v)并打印出每个元素,因为这保证不会超出矢量的边界。但是,假设我们正在教新生有关循环的知识。

假设我们将 for 循环中的第二个参数更改为v.size() + 1.at(i)会崩溃并给我们一个有意义的运行时错误std::out_of_range。但是,如果我们.at(i)更改为v[i]程序运行良好并为我打印出一个额外的数字。我在 Windows 上的 Ubuntu 18.04 上运行它,我以为当我这样做时程序会崩溃,但它没有。

所以问题是,在访问我们的容器时,我们应该使用.at()而不是[]吗?

.at() 应该在 std::vector 或 std::array 中的 [] 上使用吗?

是的,如果

  • 您无法证明您访问的索引在范围内。
  • 你不想费心证明这一点。
  • 你可能会在证明或实现中犯错误(对于人类来说,大多数时候这是"是"),并且程序中未定义的行为比at开销更昂贵。

否,如果

  • 您负担不起at的开销。

没多大关系,如果

  • 您的程序不会在未定义的行为可能导致信息丢失(或泄漏)、任何具有货币价值的东西、生命等的情况下使用。

假设我们正在教新生一分钟

使用at对于尚未发展推理程序正确性能力的新生特别有用。

另一方面,理解未定义的行为对于C++程序员也是必不可少的,向量下标及其警告也需要介绍给学生......在以后的某个时候,当他们已经对矢量感到满意时。