在C++中,11 basic_string::c_str
被定义为完全相同basic_string::data
,而后者又定义为*(begin() + n)
和*(&*begin() + n)
(when 0 <= n < size()
)完全相同.
我找不到任何要求字符串在其末尾始终具有空字符的内容.
这是否意味着c_str()
不再保证生成以null结尾的字符串?
Mik*_*kov 80
字符串现在需要在内部使用以null结尾的缓冲区.看看operator[]
(21.4.5)的定义:
要求:
pos <= size()
.返回:
*(begin() + pos)
ifpos < size()
,否则引用T
具有值 的类型的对象charT()
; 参考值不得修改.
回顾c_str
(21.4.7.1/1),我们看到它的定义是operator[]
:
返回:一个指针
p
,p + i == &operator[](i)
用于每个i
in[0,size()]
.
两者c_str
并data
需要是O(1),因此实现有效被迫使用空值终止的缓冲区.
另外,正如DavidRodríguez - dribeas在评论中指出的那样,返回值要求也意味着你可以使用它&operator[](0)
作为同义词c_str()
,因此终止空字符必须位于同一个缓冲区中(因为*(p + size())
必须等于charT()
); 这也意味着即使终结器被懒惰地初始化,也不可能在中间状态下观察缓冲区.
seh*_*ehe 23
嗯,实际上新标准确实规定.data()和.c_str()现在是同义词.但是,它并没有说.c_str()不再是零终止:)
它只是意味着你现在可以依赖.data()也是零终止的.
论文N2668定义了std :: basic_string的c_str()和data()成员,如下所示:
Run Code Online (Sandbox Code Playgroud)const charT* c_str() const; const charT* data() const;
返回:指向长度为size()+ 1的数组的初始元素的指针,其第一个size()元素等于由*this控制的字符串的相应元素,其最后一个元素是charT()指定的空字符.
要求:程序不得更改存储在字符数组中的任何值.
请注意,这不意味着任何有效的std :: string可以作为一个C字符串来对待,因为的std :: string可以包含嵌入的空值,直接作为一个const char*时将提前结束的C字符串.
我无法访问C++ 11的实际发布的最终规范,但似乎确实在规范的修订历史中某处删除了措辞:例如http://www.open-std.org/jtc1/ SC22/WG21 /文档/文件/ 2011/n3242.pdf
§21.4.7basic_string字符串操作
[string.ops]
§21.4.7.1basic_string访问器
[string.accessors]
Run Code Online (Sandbox Code Playgroud)const charT* c_str() const noexcept; const charT* data() const noexcept;
- 返回:指针p,
p + i == &operator[](i)
对于每个i
in[0,size()]
.- 复杂性:恒定时间.
- 要求:程序不得更改存储在字符数组中的任何值.
Cas*_*Cow 10
"历史"是很久以前当每个人都在单线程中工作,或者至少线程是拥有自己数据的工作者时,他们为C++设计了一个字符串类,它使字符串处理比以前更容易,并且它们重载了operator +来连接字符串.
问题是用户会做类似的事情:
s = s1 + s2 + s3 + s4;
Run Code Online (Sandbox Code Playgroud)
并且每个连接都会创建一个必须实现字符串的临时连接.
因此,有人有"懒惰评估"的脑波,这样在内部你可以存储某种带有所有字符串的"绳子",直到有人想把它作为C字符串读取,此时你会将内部表示改为连续的缓冲区.
这解决了上面的问题但是引起了其他令人头疼的问题,特别是在多线程世界中,人们期望.c_str()操作是只读的/不会改变任何东西,因此不需要锁定任何东西.在类实现中过早内部锁定以防万一有人在多线程中执行它(当时甚至没有线程标准)也不是一个好主意.事实上,除了每次复制缓冲区之外,做任何事情都要花费更多.出于字符串实现,放弃了"copy on write"实现的相同原因.
因此,制作.c_str()
一个真正不可变的操作是最明智的做法,但是可以在一个现在是线程感知的标准中"依赖"它吗?因此,新标准决定明确说明您可以,因此内部表示需要保持空终止符.
归档时间: |
|
查看次数: |
8440 次 |
最近记录: |