在 C++11 中,a 的字符std::string
必须连续存储,如第 21.4.1/5 节指出的那样:
basic_string 对象中的类字符对象应连续存储。也就是说,对于任何 basic_string 对象 s,标识 &*(s.begin() + n) == &*s.begin() + n 应适用于所有 n 值,使得 0 <= n < s.size ()。
然而,这里是第 21.4.7.1 节如何列出两个函数来检索指向底层存储的指针(强调我的):
const charT* c_str() const noexcept;
const charT* data() const noexcept;
1 返回: 一个指针 p 使得 p + i == &operator[](i) 对于 [0,size()] 中的每个 i。
2 复杂性:恒定的时间。
3 要求:程序不得更改存储在字符数组中的任何值。
对于第 3 点,我能想到的一种可能性是指针可能会因对象的以下用途而失效(第 21.4.1/6 节):
- 作为任何标准库函数的参数,将非常量 basic_string 的引用作为参数。
- 调用非 const 成员函数,除了 operator[]、at、front、back、begin、rbegin、end 和 rend。
即便如此,迭代器可能会失效,但我们仍然可以修改它们,直到它们失效。我们仍然可以使用指针,直到它也无法从缓冲区中读取。
为什么我们不能直接写入这个缓冲区?是不是因为它会使类处于不一致的状态,例如,end()
不会用新的结尾来更新?如果是这样,为什么允许直接写入类似的缓冲区std::vector
?
用例包括能够将 a 的缓冲区传递std::string
给 C 接口以检索字符串,而不是传入 avector<char>
并使用迭代器初始化字符串:
std::string text;
text.resize(GetTextLength());
GetText(text.data());