在c + + 11中string :: c_str()不再是空的吗?

在C ++ 11中, basic_string::c_str被定义为与basic_string::data完全相同,这又被定义为与*(begin() + n)*(&*begin() + n) (当0 <= n < size() )时。

我找不到任何需要string在其末尾始终为空的字符。

这是否意味着c_str()不再保证产生一个以null结尾的string?

string现在需要在内部使用空终止的缓冲区。 看operator[] (21.4.5)的定义:

需要: pos <= size()

如果pos < size() ,则返回 *(begin() + pos) ,否则返回值为charT() Ttypes对象的引用。 参考值不得修改。

回顾c_str (21.4.7.1/1),我们看到它是用operator[]来定义的:

返回:对于[0,size()]每个i ,指针p使得p + i == &operator[](i)

而且c_strdata都要求为O(1),所以实现被迫使用null终止的缓冲区。

另外,正如DavidRodríguez在注释中指出的那样,返回值的要求也意味着你可以使用&operator[](0)作为c_str()的同义词,所以终止空字符必须位于同一个缓冲区*(p + size())必须等于charT() ); 这也意味着,即使终止者被懒惰地初始化,也不可能观察处于中间状态的缓冲区。

那实际上,新标准确实规定.data()和.c_str()现在是同义词。 但是,并不是说.c_str()不再是零终止:)

这只是意味着你现在可以依靠.data()被零终止。

第N2668号文件定义了std :: basic_string的c_str()和data()成员,如下所示:

  const charT* c_str() const; const charT* data() const; 

返回:指向长度为size()+ 1的数组的初始元素的指针,该数组的第一个size()元素等于由* this控制的string的相应元素,其最后一个元素是由charT()指定的空字符。

要求:程序不应该改变存储在字符数组中的任何值。

请注意,这并不意味着任何有效的std :: string可以被视为一个Cstring,因为std :: string可以包含embedded的空值,当直接用作const char *时,它会过早地结束Cstring。

附录:

我没有访问C ++ 11的实际发布的最终规范,但似乎确实在该规范的修订历史logging中某处放弃了措辞:例如http://www.open-std.org/jtc1/ SC22 / WG21 /文档/文件/ 2011 / n3242.pdf

§21.4.7 basic_stringstring操作[string.ops]

§21.4.7.1 basic_string访问器[string.accessors]

  const charT* c_str() const noexcept; const charT* data() const noexcept; 
  1. 返回:对于[0,size()]每个i ,指针p使得p + i == &operator[](i)
  2. 复杂性:不变的时间。
  3. 要求:程序不应该改变存储在字符数组中的任何值。

“历史”是很久以前,每个人都在单线程中工作,或者至less线程是拥有自己数据的工作者,他们为C ++devise了一个string类,这使得string处理比以前更容易,并且它们被重载运算符+来连接string。

问题是用户会做这样的事情:

 s = s1 + s2 + s3 + s4; 

并且每个连接都会创build一个临时实现一个string。

因此,有人有“懒惰的评价”的脑波,这样在内部你可以存储某种“绳索”与所有的string,直到有人想读它作为一个Cstring,在这一点上,你会改变内部表示为一个连续的缓冲区。

这解决了上述问题,但是却导致了一些其他的烦恼,特别是在multithreading世界中,一个预期.c_str()操作是只读的/不会改变任何东西,因此不需要locking任何东西。 过早的内部locking在类实现中,以防万一有人在multithreading的情况下(甚至没有线程标准)也不是一个好主意。 事实上,做任何事情都比每次简单复制缓冲区都要昂贵。 同样的原因“拷贝写入”实现被放弃了string实现。

因此,使.c_str()成为一个真正不可变的操作是最明智的做法,然而,如果一个标准现在是线程感知的,那么它可以“依赖”它吗? 因此,新标准决定明确表示可以,因此内部表示需要保留空终止符。

发现得好。 这在最近通过的标准中肯定是一个缺陷。 我敢肯定,目前没有意图打破目前使用c_str所有代码。 我会提出一个缺陷报告,或者至less在comp.std.c++提出这个问题(如果问题涉及缺陷的话,通常会在委员会面前结束)。