为什么std :: string :: substr抛出异常而不是返回空字符串?

时间:2016-07-13 19:10:11

标签: c++ string substr

我一直想知道std::string substr(pos, len)方法设计背后的基本原理。它对我来说仍然没有意义,所以我决定问专家。如果std::out_of_range参数超出字符串长度加1,则该函数抛出pos异常。这有时可能不方便(甚至很烦人),但我真正关心的是一致性和最少惊喜的原则。事实证明,子串的“结束”位置pos+len允许超过字符串长度加1。一开始不允许这种情况但最终不允许这种感觉与我不一致。允许它结束我的暗示解释

返回位置pos <= i < pos+len

中的所有字符

但是,我希望函数返回一个空字符串,使pos的值超过字符串长度,而不是抛出异常。作为旁注,通过这种解释,允许pos的负值(假设它具有签名类型)甚至是明智的。

这给我留下了以下问题:

  • 这个设计对你来说是否符合逻辑?明智?您是否有满意的方法来解决不一致问题? 我能想到的唯一可能的解释是与以null结尾的字符串的兼容性。使用null终止时,指定的长度是否超过结束并不重要,而超出空字符的启动是内存错误。但是,std::string 以null结尾,而是跟踪字符串的长度。如果这是真正的原因,那么我个人称之为非常糟糕的原因。
  • 在性能方面有优势吗?我真的会感到惊讶。
  • 我是否忽略了可用性方面的优势?也许一个标准的习语或用例与其他功能一起使用,比如find?此外,我的印象是返回一个空字符串有可能简化一些代码。
  • 有没有办法在将来改变substr的行为?我想不,因为默默地破坏现有代码必须比生活中的这种扭曲更糟糕......?

1 个答案:

答案 0 :(得分:2)

这个问题实际上是基于意见的,但我会尝试逐点回答。

  • 这个设计看起来合乎逻辑吗?明智吗?这对我来说似乎合情合理。也许这样的意见来自strncmp - 样式的函数,但是通过这样的设计,你可以只传递len参数的缓冲区长度,它可以正常工作。但是,如果您尝试访问位于字符串边界之外的子字符串,那么您可能错过了一些简单的健全性检查。 std::string的内部实施并不重要。
  • 在性能方面是否有优势?我认为这不是原因。
  • 我是否忽略了可用性方面的优势?也许,请看第1点。
  • 有没有办法在将来更改substr的行为? pos超过size()的投掷异常在标准中定义,所以很可能没有。

我的观点是:这个异常(虽然我更喜欢永远不会使用它们)允许你注意缺少一些基本的健全性检查的代码,比如访问它的边界之外的缓冲区。同样的设计用于at() - 类似函数和许多其他函数。