c++ - 默认情况下,为什么 C++ 不检测何时使用 [ ] 运算符访问超出范围的 vector 元素?

标签 c++ vector indexoutofboundsexception

我知道数组是一个原始类,因此没有内置方法来检测超出范围的错误。但是, vector 类具有内置函数 .at() 可以检测到这些错误。通过使用 namespace ,任何人都可以重载 [ ] 符号以充当 .at() 函数,方法是在访问 vector 范围之外的值时抛出错误。我的问题是:为什么这个功能在 C++ 中不是默认的?

编辑:下面是重载 vector 运算符 [ ] 的伪代码示例(我相信 - 如果需要请纠正我):

Item_Type& operator[](size_t index) { // Verify that the index is legal.
if (index < 0 || index >= num_items) {
   throw std::out_of_range
     ("index to operator[] is out of range");
}
 return the_data[index]
}

我相信这个函数可以写入用户定义的命名空间并且相当容易实现。如果这是真的,为什么它不是默认值?

最佳答案

对于通常像 [] 这样便宜的东西,边界检查会增加大量开销。

考虑

int f1(const std::vector<int> & v, std:size_t s) { return v[s]; }

此函数转换为 just three lines of assembly :

    movq    (%rdi), %rax
    movl    (%rax,%rsi,4), %eax
    ret

现在考虑使用 at() 的边界检查版本:

int f2(const std::vector<int> & v, std:size_t s) { return v.at(s); }

这变成了

    movq    (%rdi), %rax
    movq    8(%rdi), %rdx
    subq    %rax, %rdx
    sarq    $2, %rdx
    cmpq    %rdx, %rsi
    jae .L6
    movl    (%rax,%rsi,4), %eax
    ret
.L6:
    pushq   %rax
    movl    $.LC1, %edi
    xorl    %eax, %eax
    call    std::__throw_out_of_range_fmt(char const*, ...)

即使在正常(非抛出)代码路径中,也有 8 行汇编 - 几乎是原来的三倍。

关于c++ - 默认情况下,为什么 C++ 不检测何时使用 [ ] 运算符访问超出范围的 vector 元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30181568/

相关文章:

C++ 帮助定义和使用结构 vector 的 vector

java - 二维数组上的 ArrayIndexOutOfBoundsException 错误

java - 我有一个 IndexOutOfBoundsException 并且不明白为什么

c++ - 如何将 lambda 函数排队到 Qt 的事件循环中?

r - 根据相同数据框的逻辑获取列名向量

c++ - 在 C++ 中调用指向成员函数的指针时出错

c++ - 从 C++ vector 中提取引用

java - 如何修复数组 OutOfBoundsException?

c++ - 使用数组在C++中创建卡片组数据结构

c++ - 依赖于模板参数的成员变量和构造函数