std::string
为什么find
有std::vector
成员函数,而std::find
和朋友没有成员函数?
在字符串上使用{{1}}有什么问题吗?
答案 0 :(得分:12)
这主要是出于历史原因,但不仅仅是。
字符串库和STL(由A. Stepanov开发的容器/算法库最终成为C ++标准库的一部分)是独立开发的,它们采用了不同的约定。
然而,由于它们最终都融合到C ++标准库中,因此C ++标准确实努力统一这些语法约定并允许string
使用STL算法,这就是为什么类string
除begin()
等其他成员函数外,还具有end()
和substr()
等成员函数。
除了向后兼容性之外,还有另一个原因string
提供成员函数,例如find()
:与容器不同,容器用于访问或操作的通用算法元素,字符串通常被认为是值本身而不是值的集合(即char
s的序列)。因此,将操纵string
值的算法封装到string
类的成员函数中是有意义的。
因此,在其设计中,C ++标准库支持string
s的这两种视图:作为值集合和值本身。
<强>更新强>
你的第一句话“std::vector
和朋友没有它”是不完全正确的。至少,如果您将std::vector
的朋友范围扩展为std::set
,std::multiset
,std::map
,std::multimap
,std::unordered_set
和{ {1}}(换句话说,几乎与C ++标准库中的所有关联容器相同)。
某些数据结构确实在其接口上具有某些通用STL算法的成员函数版本:这要么表明这些算法的实现比那些特定数据结构的通用对应物更有效(例如{ {1}}),或者需要专门的实现,因为通用算法根本不能应用于那些数据结构(例如std::unordered_map
,修改容器中的值)。
答案 1 :(得分:4)
std::string::find
(*)的语义与std::find
的语义完全不同。在算法的情况下,它将在容器内找到一个元素,如果您应用于std::string
,则意味着找到字符为X 的位置。
成员函数std::string::find
(除了一个带有单个charT
的变体)具有不同的目的,他们找到子串(即一系列值而不是一个单值)。
接下来的问题是为什么只有一个charT
的调用就会出现一个需要std::find
的重载。正如Andy在他的回答中提到的那样,STL和字符串库的实现是分开进行的。然后将迭代器添加到std::string
组件中。当迭代器被添加到std::string
时,这个重载已经存在,即使它不存在,语义仍然与std::find
有点不同,因为std::string::find
的其余部分},而不是迭代器,他们采取并返回位置。这并不意味着一个人不能用另一个来实现,只有那些代码会更复杂。
(*)跟我一起......阅读std::string
,好像拼写为std::basic_string<>