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

Why does std::string::substr throw an exception instead of returning an empty string?

一段时间以来,我一直在想 std::stringsubstr(pos, len) 方法设计背后的基本原理。这对我来说仍然没有意义,所以我决定请教专家。如果 pos 参数超过字符串长度加一,该函数将抛出 std::out_of_range 异常。有时这可能会带来不便(甚至烦人),但我真正关心的是一致性和最少意外原则。原来是允许子串的"end"位置pos+len超过字符串长度加一。一开始就不允许这样做,但最后却不允许,这对我来说是不一致的。允许它结束对我的解释

return 位置 pos <= i < pos+len

的所有字符

但是,我希望函数 return 一个空字符串,值 pos 超过字符串长度,而不是抛出异常。作为旁注,根据这种解释,允许 pos 的负值甚至是明智的(前提是它具有带符号的类型)。

这给我留下了以下问题:

这个问题真的太主观了,不过我会尽量逐条回答。

  • 您觉得这个设计合乎逻辑吗?明智? 对我来说这似乎合乎逻辑。也许这样的意见来自 strncmp 风格的函数,但通过这样的设计,您只需为 len 参数传递缓冲区长度,它就可以正常工作。但是,如果您试图访问位于字符串边界之外的子字符串,那么您可能会错过一些简单的健全性检查。 std::string 的内部实现无关紧要。
  • 在性能方面有优势吗?我觉得不是这个原因。
  • 我是否忽略了可用性方面的优势?也许,看看第 1 点。
  • 有什么方法可以改变 substr 在未来的行为吗?pos 超过 size() 时抛出异常是在标准中定义的,所以大多数可能没有。

我的观点是:这个异常(尽管我宁愿从不使用它们)允许您注意到缺少一些基本健全性检查的代码,例如访问其边界之外的缓冲区。 at()-like 函数和许多其他函数中使用了相同的设计。