首先从标准中摘录一些:
string::operator[]()
的规范:
const_reference运算符[](size_type pos)const;
reference operator [](size_type pos);
需要:pos< = size()。
返回:*(begin()+ pos)如果pos< size(),否则引用一个 类型为T的对象,其值为charT();参考值不得 修改。
复杂性:恒定时间。
string::c_str()
和string::data()
的规范:
const charT * c_str()const noexcept;
const charT * data()const noexcept;
返回:指针p,每个i中的p + i == &operator[](i)
[0,大小()]。
复杂性:恒定时间。
通过组合这两个规范,我们可以看到p
/ c_str()
返回的指针data()
必须满足p[0...size()-1]
指定字符串的元素,{ {1}}等于p[size()]
,它指定值为operator[](size())
的对象。由于指针上的加法运算符用于获取字符串元素和最后一个charT()
对象的地址,因此它们必须位于单个数组中(您不能只使用字符串元素并创建一个charT()
即时对象并将其返回)。那么可以肯定地说,在C ++ 11中,charT()
保证在其底层存储中具有终止空字符吗?
编辑:我对未能注意到我的问题的道歉是重复的。但是,我在这里得到的答案似乎与那个重复问题的答案相矛盾。
另外,我应该削弱我的假设:str::string
的基础表示应保留足够的空间来保存终止空字符,并自由设置std::string
值直到{{ 1}} / charT()
被调用。 (即底层存储必须能够随时保留至少c_str()
个元素。)
答案 0 :(得分:2)
不,不是。 std::string
可以延迟计算c_str()
和data()
所需的结果。在调用这些方法之前,无法保证空终结符存在于底层存储中。
标准只保证字符串字符的连续性。
答案 1 :(得分:1)
那么可以肯定地说,在C ++ 11中,
std::string
保证在其底层存储中具有终止空字符吗?
我不知道你怎么能从两个引号中得出这个结论。特别是,在您调用c_str()
或data()
之前,我在这些引号中没有看到任何需要底层实现来维护终止空字符的引号。
答案 2 :(得分:1)
不......确切地说出它的内容:operator[](size()) == CharT()
和c_str()[size()] == 0
以及data()[size()] == 0
。
"底层存储"在实现中定义了一个0,并且对你的程序也没有任何影响,因为除了operator[]
和c_str()
这些在{{size()
定义好的东西之外无法访问它1}}。