为什么在C++中使用"vector.at(x)"比"vector [x]"更好?

Lam*_*a87 29 c++ exception vector

如果我想获得向量中的值,我可以使用两个选项:使用[]运算符.或者我可以使用函数.at示例来使用:

vector<int> ivec;
ivec.push_back(1);
Run Code Online (Sandbox Code Playgroud)

现在我可以做两件事

int x1 = ivec[0];
int x2 = ivec.at(0); // or
Run Code Online (Sandbox Code Playgroud)

我听说使用at是一个更好的选择,因为当我使用该选项时,我可以在异常中抛出这个.

有人可以解释一下吗?

Naw*_*waz 54

之间的区别c[i]c.at(i)at()抛出std::out_of_range异常,如果i向量的范围外时,而operator[]只是调用未定义的行为,这意味着任何事情都有可能发生.

没有人说at()胜过operator[].这取决于具体情况.当at()执行范围检查时,可能总是不可取,特别是当您的代码本身确保索引永远不会超出范围时.在这种情况下,operator[]更好.

考虑以下循环:

for(size_t i = 0 ; i < v.size(); ++i)
{
   //Should I use v[i] or v.at(i)?
}
Run Code Online (Sandbox Code Playgroud)

在这样的循环中,operator[]at()成员函数相比,总是更好的选择.

我希望at()当我想要它在无效索引的情况下抛出异常,这样我就可以在catch{ ...}块中做替代工作.例外可帮助您将普通代码与例外/替代代码分开,如下所示:

try
{
   size_t i = get_index(); //I'm not sure if it returns a valid index!

   T item = v.at(i); //let it throw exception if i falls outside range

   //normal flow of code
   //...
}
catch(std::out_of_range const & e)
{
   //alternative code
}
Run Code Online (Sandbox Code Playgroud)

在这里你可以检查i自己,确保它是一个有效的索引,然后调用operator[]而不是at(),但它会使用if-else块混合普通代码和替代代码,这使得很难读取正常的代码流.如果你看到上面的内容,try-catch提高了代码的可读性,因为它实际上将普通代码与替代代码分开,从而产生了整洁干净的代码.

  • 不要低估那里有多少白痴,以及有多少白痴教C++.;-) (7认同)
  • "没有人说`at()`更好" - 哈!你会感到惊讶. (4认同)

das*_*ght 10

at和之间的唯一区别[]at执行范围检查,而[]不是.如果您已经检查了范围或者已经构建了索引,使得它不能超出范围,并且需要重复访问项目,则可以通过选择[]而不是a来节省一些CPU周期at.

单次检查和多次访问的示例:

size_t index = get_index(vect);
if (index < 0 || index >= vect.size()) return;
if (vect[index] > 0) {
    // ....
} else if (vect[index] > 5) {
    // ....
} else ....
Run Code Online (Sandbox Code Playgroud)

将索引构造为内部限制的情况示例:

for (size_t i = 0 ; i != vect.size() ; i++) {
    if (vect[i] > 42) {
        // ....
    }
}
Run Code Online (Sandbox Code Playgroud)