std::string s1;
std::string s2;
assert(strlen(s1.c_str()) == 0);
assert(s1.c_str() == s2.c_str());
这两个断言总是为真吗?
我使用的是 C++11,我已经检查了标准,§21.4.2 中的表 63 说:
data() a non-null pointer that is copyable and can have 0 added to it
size() 0
capacity() an unspecified value
我认为c_str()
和data()
是一样的。但是我对这个定义有一些疑问。
“可以是否添加了 0”==“必须且总是添加了 0”?
是否所有默认构造的 std::string 共享同一个底层缓冲区?
我在gcc上测试,这两个断言是真的。我想知道这些是否对所有编译器都适用?
最佳答案
第一个断言保证成功。 c_str()
总是返回一个指向以 null 结尾的字符串的指针,该字符串的内容与 std::string
对象所持有的内容相同,该对象对于 s1
。
第二个断言不保证成功。如果内容相同,则无需从 std::string
返回的 c_str()
相同。默认构造的字符串不需要共享相同的底层缓冲区。那将是特定标准库实现的实现细节。 (我认为 libstdc++ 会根据某些向后兼容性(?)原因的配置做类似的事情,如果我没记错的话,请参阅 --enable-fully-dynamic-string
configure
选项)。
请注意,在 C++11 之前,data()
不 具有与 c_str()
相同的效果。 data()
不能保证提供指向以 null 结尾的字符串的指针。如果字符串为空,则不允许取消引用它返回的指针。因此,在 C++11 之前,将示例中的 c_str()
替换为 data()
会导致调用 strlen
时出现未定义的行为>.
“and can have 0 added to it”的措辞有点奇怪,我不完全确定它应该传达什么,但对于 C++11(草案 N3337) data()
的返回值在 [string.accessors]/1 中进一步指定因此 data() + i == &operator[](i)
对于 [0,size()]
范围内的所有 i
和operator[]
在 [strings.access]/2 中指定无条件地为 operator[](size())
返回对 CharT()
(又名空字符)的引用。
奇怪的措辞也已通过 2018 年的编辑更改被替换,请参阅 https://github.com/cplusplus/draft/pull/1879 .
关于c++ - 默认构造的 std::string c_str() 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72654693/