繁体   English   中英

std :: string是否需要将其字符存储在连续的内存中?

[英]Does std::string need to store its character in a contiguous piece of memory?

我知道在C ++ 98中, std::basic_string<>std::vector<>都不需要使用连续存储。 一旦被指出,这被视为对std::vector<>的疏忽,如果我没记错的话,用C ++ 03修复了。

似乎记得读过有关讨论要求std::basic_string<>在C ++ 11仍被称为C ++ 0x时使用连续存储,但我当时没有密切关注讨论,并且仍然局限于C ++ 03在工作,所以我不确定它是什么。

那么使用连续存储需要std::basic_string<>吗? (如果是这样,那么标准的哪个版本首先需要它?)

如果您想知道:如果您将&str[0]的结果传递给期望连续写入内存的函数,则这很重要。 (我知道str.data() ,但由于显而易见的原因,旧代码不使用它。)

C ++ 11标准 ,basic_string 21.4.1.5,

basic_string对象中的char类对象应连续存储。 也就是说,对于任何basic_string对象,标识&*(s.begin()+ n)==&* s.begin()+ n应该适用于n的所有值,使得0 <= n <s.size ()。

在c ++ 03中,无法保证字符串的元素会被连续存储。 [basic.string]是

  1. 对于类似char的类型charT,类模板basic_string描述了可以存储由不同数量的任意类似char的对象组成的序列的对象(第21节)。 序列的第一个元素位于零位。 如果给定的类似char的类型从上下文中清楚,则这样的序列也称为“字符串”。 在本节的其余部分中,charT表示类似于char的类型。 通过作为模板参数传递的Allocator类,通过类basic_string的成员函数根据需要分配和释放字符串的存储。 Allocator :: value_type应与charT相同。
  2. 类模板basic_string符合Sequence的要求,如(23.1.1)中所述。 另外,因为basic_string支持的迭代器是随机访问迭代器(24.1.5),所以basic_string符合(23.1)中规定的可逆容器的要求。 389 ISO / IEC 14882:2003(E)ISO/ IEC 21.3类模板basic_string 21字符串库
  3. 在所有情况下,size()<= capacity()。

然后在C ++ 17中他们也改变了它

  1. 类模板basic_string描述了可以存储由不同数量的任意类似char的对象组成的序列的对象,其中序列的第一个元素位于零。 如果它所保持的类似char的对象的类型从上下文中清楚,则这样的序列也称为“字符串”。 在本条款的其余部分中,basic_string对象中保存的类似char的对象的类型由charT指定。
  2. basic_string的成员函数使用作为模板参数传递的Allocator类的对象来为包含的类似char的对象分配和释放存储。
  3. basic_string是一个连续的容器(23.2.1)。
  4. 在所有情况下,size()<= capacity()。

强调我的

所以预先C ++ 17它不能保证,但现在它是。

由于std::string::data强加的约束,这种非保证几乎没有用,因为调用std::string::data会给你一个连续的字符串数组。 因此,除非实现按需执行此操作,并且在恒定时间内字符串将是连续的。


如果您想知道:如果您将&str[0]的结果传递给期望连续写入内存的函数,则这很重要。 (我知道str.data() ,但由于显而易见的原因,旧代码不使用它。)

operator[]的行为也发生了变化。 在C ++ 03中我们有

返回:如果pos <size(),则返回data()[pos]。 否则,如果pos == size(),则const版本返回charT()。 否则,行为未定义。

因此,如果在s为空时尝试&s[0] ,则只保证const版本具有已定义的行为。 在C ++ 11中,他们将其更改为:

如果pos <size(),则返回: *(begin()+ pos)。 否则,返回对charT类型的对象的引用,其值为charT(),其中修改对象会导致未定义的行为。

所以现在,当s为空时,如果你尝试&s[0] ,那么const和非const版本都有定义的行为。

根据草案标准N4527 21.4 / 3类模板basic_string [basic.string]

basic_string是一个连续的容器(23.2.1)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM