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

原文 标签 c++ vector indexoutofboundsexception

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

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

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++ - 将Eigen与用于自动微分的定制复数一起使用

c++ - 使用混合C和C++的函数的 undefined reference

c++ - 有没有更好的方法可以接收此输入? C++

java - 对ArrayIndexOutOfBoundsException有疑问吗?

java - 如何在Java 2D数组中交换具有特定索引的列?

c++ - 编码H.264时,avcodec_encode_video2()出现分段错误

c++ - 等时执行以运行4和8线程

r - 根据R中的数字 vector 绘制字符 vector

c++ - 从存储在 vector 中的指针获取对象属性

java - 为什么索引超出范围?