提问人:sbi 提问时间:10/14/2015 最后编辑:NathanOliversbi 更新时间:5/15/2017 访问量:5203
std::string 是否需要将其字符存储在连续的内存中?
Does std::string need to store its character in a contiguous piece of memory?
问:
我知道在 C++98 中,既不需要也不需要使用连续存储。一旦有人指出这一点,就被视为一种疏忽,如果我没记错的话,C++03 修复了它。std::basic_string<>
std::vector<>
std::vector<>
我似乎记得当 C++11 还被称为 C++0x 时,我读过关于需要使用连续存储的讨论,但当时我没有密切关注讨论,并且仍然仅限于 C++03 在工作中,所以我不确定它变成了什么。std::basic_string<>
那么是否需要使用连续存储呢?(如果是这样,那么哪个版本的标准首先需要它?std::basic_string<>
如果您想知道:如果您有代码将 &str[0]
的结果传递给需要写入连续内存块的函数,这一点很重要。(我知道str.data(),
但由于显而易见的原因,旧代码不使用它。
答:
C++11 标准,basic_string 21.4.1.5,
应将 basic_string 对象中的类似字符的对象存储起来 连续。也就是说,对于任何basic_string对象,恒等式 &*(s.begin() + n) == &*s.begin() + n 应为 n 的所有值成立 使得 0 <= n < s.size()。
根据标准草案 N4527 21.4/3 类模板basic_string [basic.string]:
basic_string是一个连续的容器(23.2.1)。
在 c++03 中,不能保证字符串的元素是连续存储的。[基本字符串] 是
- 对于类似 char 的类型 charT,类模板basic_string描述可以存储 由任意数量的类字符对象组成的序列(第 21 条)。第一个元素 序列位于位置 0。如果给定的类字符类型是明确的,则这样的序列也称为“字符串” 从上下文。在本子句的其余部分,charT 表示这种给定的类 char 类型。字符串的存储 根据需要由类 basic_string 的成员函数通过 作为模板参数传递的 Allocator 类。分配器::value_type应与 图表。
- 类模板basic_string符合 (23.1.1) 中指定的 Sequence 的要求。 此外,由于 basic_string 支持的迭代器是随机访问迭代器 (24.1.5), basic_string符合 (23.1) 中规定的可逆容器的要求。 389 ISO/IEC 14882:2003(E) ISO/IEC 21.3 类模板 basic_string 21 字符串库
- 在所有情况下,size() <= capacity()。
然后在 C++17 中,他们也改变了它
- 类模板basic_string描述可以存储由不同数字组成的序列的对象 序列的第一个元素位于零位置的任意字符状对象。这样的序列也是 称为“字符串”,如果它所包含的类字符对象的类型在上下文中是清楚的。在剩下的时间里 子句,basic_string对象中保存的类似 char 的对象的类型由 charT 指定。
- basic_string的成员函数使用作为模板参数传递的 Allocator 类的对象 为包含的类字符对象分配和释放存储空间233。
- basic_string是一个连续的容器(23.2.1)。
- 在所有情况下,size() <= capacity()。
强调我的
所以在 C++17 之前,它不能保证,但现在是。
由于施加了这种非保证的约束,因此几乎毫无意义,因为调用会为您提供字符串中字符的连续数组。因此,除非实现是按需且在恒定时间内执行此操作,否则字符串将是连续的。std::string::data
std::string::data
如果您想知道:如果您有代码将
&str[0]
的结果传递给需要写入连续内存块的函数,这一点很重要。(我知道str.data(),
但由于显而易见的原因,旧代码不使用它。
的行为也发生了变化。在 C++03 中,我们有operator[]
返回:如果 pos < size(),则返回 data()[pos]。否则,如果 pos == size(),则 const version 返回 charT()。否则,行为是未定义的。
因此,如果您尝试 when 为空,则只能保证版本具有定义的行为。在 C++11 中,他们将其更改为:const
&s[0]
s
返回:*(begin() + pos) if pos < size()。否则,返回对 type 对象的引用 值为 charT() 的 charT,其中修改对象会导致未定义的行为。
因此,现在如果您尝试 when 为空,则版本和非版本都定义了行为。const
const
&s[0]
s
评论
string::data()
string::data()
string::data()
string::data()
上一个:如何减少序列化当前所需的样板文件
下一个:检测扫描文档中的空页
评论
str.data()
str.data()
const char*
绳索
。所以,在实践中,如果我是你,我只会偷看你的工作 C++03 的标准库(如果偏执狂),然后假设它总是连续的。std::basic_string