我一直在思考关于
这让我有以下几个问题:
std::string
的substr(pos, len)
方法设计背后的原理。它仍然不合理,所以我决定向专家请教。如果pos
参数超过字符串长度加一,该函数将抛出一个std::out_of_range
异常。有时这可能会很不方便(甚至让人烦恼),但我的真正关注点是一致性和最小惊奇原则。结果发现,子字符串的“结束”位置pos+len
可以超过字符串长度加一。对于开头不允许这样做,而对于结尾允许这样做,这种感觉不一致。对我来说,允许结尾做到这一点暗示了以下解释:
返回所有位置pos <= i < pos+len
的字符
pos
的值超过字符串长度,那么我希望函数返回一个空字符串,而不是抛出异常。顺便提一下,如果按照这种解释,允许pos
的负值(如果它具有带符号类型)甚至是有意义的。这让我有以下几个问题:
- 您认为这种设计是否合乎逻辑?是否合理?您有解决这种不一致性的满意方法吗?
我能想到的唯一可能的解释是与空终止字符串兼容。对于空终止,指定的长度超过结尾并不重要,而从空字符之后开始则是内存错误。然而,
std::string
没有空终止,而是跟踪字符串的长度。如果这是真正的原因,那么我个人认为这是一个非常糟糕的原因。 - 在性能方面有什么优势吗?我会感到惊讶。
- 我是否忽略了可用性方面的优点?也许是与其他函数(如find)结合使用的标准习语或用例?在这里,我印象中返回一个空字符串有潜力简化一些代码。
- 有没有办法在将来更改
substr
的行为?我想答案是否定的,因为默默地破坏现有代码比接受这种曲折要糟糕得多...
pos
到结尾的子字符串”变得容易,这并不是一个罕见的操作。将第二个参数视为返回的子字符串中字符数的上限。 - T.C.pos/=2
循环调用函数直到停止抛出?最好使用有用的消息(ex:“清洗您的输入!”
)进行断言失败。但是,STL是写于许多年前,也许当时人们并不知道更好的方法。现在,我们必须接受这种行为。 - KABoissonneaultsubstr
会在pos > length + 1
时抛出异常?标准规定如果pos > size()
则会抛出 out_of_range 异常。 - NathanOliverstd::string
在其实现中 不是 以空字符结尾的? - Ternveinc_str
就可以在不复制的情况下工作,但我认为至少在C++03中你不能依赖于此。真正的问题是'\0'
是一个合法的字符在std::string
中,因为长度不是由空字符确定的。因此,我认为依赖于空字符终止的接口对于std::string
来说是不自然的。 - tglas