在C++ 11及更高版本中,std :: string :: operator []是否进行边界检查?

Nat*_*ica 27 c++ string arrayaccess c++11 c++14

我见过多次std::string::operator[]不做任何边界检查.甚至string :: at和string :: operator []之间有什么区别?,在2013年询问,答案说operator[]不做任何边界检查.

我的问题是,如果我在[string.access]中查看标准(在本例中为草案N3797)

const_reference operator[](size_type pos) const;
reference operator[](size_type pos);
Run Code Online (Sandbox Code Playgroud)
  1. 要求: pos <= size().
  2. 返回: *(begin() + pos) if pos < size().否则,返回对charT具有value 的类型对象的引用charT(),其中修改对象会导致未定义的行为.
  3. 投掷:没什么.
  4. 复杂性:恒定时间.

这使我相信operator[]必须进行某种边界检查以确定它是否需要返回字符串的元素或默认值charT.这个假设是否正确,operator[]现在需要进行边界检查?

Lig*_*ica 44

措辞有点令人困惑,但如果你仔细研究它,你会发现它实际上非常精确.

它说:

  • 前提条件是参数to []要么是= n,要么是< n.
  • 假设满足前提条件:
    • 如果它< n那么你得到你要求的角色.
    • "否则"(即如果它是n)则得到charT()(即空字符).

但是,没有规则,当你打破的前提条件定义,并在检查= ň可以通过实际存储隐含满足(但没有明确授权可以)charT()在位置ñ.

因此,实现不需要执行任何边界检查......而常见的检查不会.

  • *"但是,当你打破前提条件时,没有规定任何规则"*可能是你答案中最重要的部分;) (7认同)
  • 也许,有趣的是要记住c_str和data()执行自c ++ 11以来的相同功能,并且它们不会使迭代器无效.这意味着charT()存储在位置n. (3认同)
  • @AntonioGarrido我猜一个神秘的实现仍然没有.根据我的理解,它仍然可以检查`n == pos`情况并返回对静态`charT`实例的引用,`data()`和`c_str`可以分配实习状态的副本加上默认的const.`charT`结尾.不可行,但恕我直言允许. (2认同)
  • @LightnessRacesinOrbit我通常知道,但是来自第1行的N4140状态的§21.4.7.1:<"in [0,size()]"由于...而不是)非常包括给我;-)或引用更多一点<1返回:指针p使得p + i ==&operator [](i)为[0,size()]中的每个i (2认同)

Sup*_*kus 14

operator[] 做了某种界限检查确定......

不,不.有前提条件

需要:pos <= size().

它可以只是ASSUME它总是可以返回字符串的元素.如果不满足此条件:未定义的行为.

operator[]会可能只是从POS字符串的开始递增指针.如果字符串更短,那么它只是返回对字符串后面的数据的引用,无论它是什么.就像简单C数组中的经典界限一样.

为了完整地说明pos == size()它可以charT在其内部字符串数据的末尾分配额外的情况.因此,只需在没有任何检查的情况下递增指针,仍然会提供所述行为.