我知道在C ++ 98中,std::basic_string<>
和std::vector<>
都不需要使用连续存储。一旦被指出,这被视为对std::vector<>
的疏忽,如果我没记错的话,用C ++ 03修复了。
我似乎要记得在C ++ 11仍被称为C ++ 0x时读过有关要求std::basic_string<>
使用连续存储的讨论,但我没有按照讨论进行讨论当时紧接着,我仍然受限于C ++ 03的工作,所以我不确定它是什么。
使用连续存储需要std::basic_string<>
吗? (如果是这样,那么标准的哪个版本首先需要它?)
如果您想知道:如果您将&str[0]
的结果传递给期望连续写入内存的函数,则这很重要。 (我知道str.data()
,但由于显而易见的原因,旧代码不使用它。)
答案 0 :(得分:27)
C++11 standard,basic_string 21.4.1.5,
应存储basic_string对象中类似char的对象 连续。也就是说,对于任何basic_string对象,标识 &amp; *(s.begin()+ n)==&amp; * s.begin()+ n将保留n的所有值 使得0 <= n <0。 s.size()。
答案 1 :(得分:15)
在c ++ 03中,无法保证字符串的元素会被连续存储。 [basic.string]是
- 对于类似char的类型charT,类模板basic_string描述了可以存储的对象 由不同数量的任意类似char的对象组成的序列(第21条)。第一个元素 序列在零位。如果给定的类似char的类型是明确的,则这样的序列也称为“字符串” 从上下文。在本节的其余部分中,charT表示类似于char的类型。存储字符串 由basic_string类的成员函数根据需要分配和释放 Allocator类作为模板参数传递。 Allocator :: value_type应与 图表。
- 类模板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字符串库
- 在所有情况下,size()&lt; = capacity()。
醇>
然后在C ++ 17中他们也改变了它
- 类模板basic_string描述了可以存储由不同数字组成的序列的对象 任意类似char的对象,其中序列的第一个元素位于零位置。这样的序列也是 如果它保存的类似char的对象的类型从上下文中清楚,则称为“字符串”。在其余部分 子句,basic_string对象中保存的类似char的对象的类型由charT指定。
- basic_string的成员函数使用作为模板参数传递的Allocator类的对象 为包含的类似char的对象分配和释放存储空间.233
- basic_string是一个连续的容器(23.2.1)。
- 在所有情况下,size()&lt; = capacity()。
醇>
强调我的
所以预先C ++ 17它不能得到保证,但现在却是。
由于std::string::data
强加的约束,这种非保证几乎没有用,因为调用std::string::data
会给你一个连续的字符串数组。因此,除非实现按需执行此操作,并且在不变的时间内,字符串将是连续的。
如果您想知道:如果您将
&str[0]
的结果传递给期望连续写入内存的函数,则这很重要。 (我知道str.data()
,但由于显而易见的原因,旧代码并没有使用它。)
operator[]
的行为也发生了变化。在C ++ 03中我们有
返回:如果pos&lt; size(),返回data()[pos]。否则,如果pos == size(),则为const version返回charT()。否则,行为未定义。
因此,当const
为空时,如果您尝试&s[0]
,则只保证s
版本具有已定义的行为。在C ++ 11中,他们将其更改为:
返回: *(begin()+ pos)如果pos&lt;尺寸()。否则,返回对类型对象的引用 具有值charT()的charT,其中修改对象会导致未定义的行为。
因此,如果您const
为空时尝试const
,&s[0]
和非s
版本都会定义行为。
答案 2 :(得分:2)
根据标准草案N4527 21.4 / 3类模板basic_string [basic.string] :
basic_string是一个连续的容器(23.2.1)。