为啥字符串不是向量的(子类)?

Posted

技术标签:

【中文标题】为啥字符串不是向量的(子类)?【英文标题】:Why is string not a (subclass of) vector?为什么字符串不是向量的(子类)? 【发布时间】:2015-07-14 15:43:21 【问题描述】:

C 字符串是字符数组。

向量是 C++ 中的新数组。

那么为什么不是字符串向量(字符的)?

向量和字符串的大多数方法似乎也是重复的。在 C++ 中让字符串成为不同的东西有什么原因吗?

【问题讨论】:

相关:***.com/questions/19730488/stl-is-a-string-a-vector 向量不是 C++ 中的新数组。数组是 C++ 中的新数组;)。更准确地说:std::array 最接近 c 样式数组 ps:甚至可能有一个在后台使用向量的字符串实现。但是,当使用这样的字符串时,您不会注意到,因为这是一个实现细节(因此不应泄漏到公共接口)。 @PSkocik c_str 虽然是 const ,所以实际的字符串对象也可能是 const (不能抛弃 const )。不过,您仍然可以使用可变向量成员实现 string @PSkocik,调用c_str() 不能使现有的迭代器、指针和引用无效。如果reserve 调用需要重新分配,那么它将无效,因此您的建议不符合要求。 【参考方案1】:

这几乎只是历史性的。对于T==char,字符串和向量是并行开发的,几乎没有考虑如何将它们视为一回事。

这也是为什么标准容器既好又通用的原因,而 std::basic_string 是成员函数之后的一个整体。

边缘案例优化机会使得以任何标准方式将std::basic_string<T, Alloc> 转换为std::vector<T, Alloc> 变得困难或不可能。以小字符串优化为例。虽然,现在 GCC 的写时复制机制已正式失效,但我们离我们更近了一点。

不过,合法取消引用std::string::end()(并为您的麻烦获取'\0')的能力仍然存在问题。 .c_str() 的一堆相当严格的迭代器失效规则基本上阻止我们从一开始就使用 std::vector<char>

tl;dr:当你创建骆驼时会发生这种情况

【讨论】:

@JonathanWakely:我认为 SSO 是不合规的(尤其是从 C++11 开始,解决了这些标准的歧义和缺陷),甚至 GCC 现在/即将迁移到合规的 std::string 实现?完全承认我没有对这个特定问题进行太多详细的研究,因为它只是为了给出一个一般性的想法。不过,我当然会删除事实的不准确之处...... 这对我来说是个新闻。 COW 死了,GCC 5.1 迁移到 SSO,你是这么想的吗? “虽然,现在 GCC 的写时复制机制正式失效,我们离我们更近了一点。”不是真的,虽然这个特殊的障碍已经消除,但有一个新的障碍:委员会注意允许在 C++11 中对 basic_string 进行小字符串优化,但是由于强制指针和引用,小向量优化是/仍然被禁止的应在移动或交换期间保持有效,甚至强制不得移动、复制或交换元素(在一般容器要求中,请参阅 N3376 中的 §23.2.1/8)。 @ArneVogel:前进一步,后退一步,是我试图提出的想法。 @Barry:因为骆驼是委员会设计的马。【参考方案2】:

Vector vs string 中的各种答案表明vectorstring 之间的接口存在一些差异,并且由于标准中的典型模式是使用静态多态性而不是动态多态性,因此它们被创建为两个不同的类。

由于字符串确实具有与向量不同的特征,因此您似乎不想使用公共继承,但我认为标准中没有任何内容会禁止受保护或私有继承,或组合以提供底层空间管理。

此外,我怀疑 string 可能是更早开发的,并且与 vector 正交,这可能解释了为什么如果与 vector 并行开发,更有可能成为免费算法的成员方法。

【讨论】:

【参考方案3】:

是的,因为 vector 是一个可以包含 T 的容器,而 std::string 是 char* 的包装器,不能包含 int 或其他数据类型。以任何其他方式拥有它没有任何意义。

【讨论】:

我想问题是为什么 std::string 不是 std::vector 的 typedef。 太模糊了。你可以拥有typedef vector<char> string;,这从表面上看是完全合理的。实际上,将字符串建模为向量会导致短字符串和空终止符出现各种问题。 @MagunRa 不,他明确要求子类化

以上是关于为啥字符串不是向量的(子类)?的主要内容,如果未能解决你的问题,请参考以下文章

为啥带有两个元素的初始化器语法将一个元素放入字符串向量而不是两个?

使用 push_back 向向量添加非空字符串,向量内容为空。为啥字符串没有添加到向量中?

为啥我的编译器对 c 字符串类型的向量存在内存问题?

为啥我不能从数据库中保存和检索我的向量(二进制)和特殊字符?

为啥 UIPopoverController 不是 UIViewController 的子类?

为啥我不能在使用 sort_by_key 对向量进行排序时使用返回引用的键函数?