默认构造的 std::string c_str() 值

Min*_*Gao 3 c++ stdstring

std::string s1;\nstd::string s2;\nassert(strlen(s1.c_str()) == 0);\nassert(s1.c_str() == s2.c_str());\n
Run Code Online (Sandbox Code Playgroud)\n

这两个断言总是正确的吗?

\n

我使用C++11,并且我检查了标准,\xc2\xa721.4.2中的表63说:

\n
\n

data() 一个可复制的非空指针,可以添加 0

\n

大小() 0

\n

capacity() 一个未指定的值

\n
\n

我认为c_str()与 相同data()。但我对这个定义有一些疑问。

\n
    \n
  1. 是否“可以添加 0”==“必须且始终添加 0”?

    \n
  2. \n
  3. 所有默认构造的 std::string 是否共享相同的底层缓冲区?

    \n
  4. \n
\n

我在gcc上测试,这两个断言是正确的。我想知道这些对于所有编译器来说总是正确的吗?

\n

use*_*522 5

第一个断言保证会成功。c_str()始终返回一个指向以 null 结尾的字符串的指针,该字符串与对象所保存的字符串内容相同std::string,对于两者来说都是空字符串s1

第二个断言不保证成功。如果内容相同,则不要求c_str()a 返回的std::string内容相同。默认构造的字符串不需要共享相同的底层缓冲区。这将是特定标准库实现的实现细节。(我认为 libstdc++ 会根据某些向后兼容性(?)原因的配置执行类似的操作,如果我没记错的话,请参阅该选项)。--enable-fully-dynamic-string configure

请注意,在 C++11 之前,data()没有与. 不保证给出指向空终止字符串的指针。如果字符串为空,则不允许取消引用它返回的指针。因此,在 C++11 之前,在示例中替换为会导致调用 时出现未定义的行为。c_str()data()c_str()data()strlen


“并且可以添加 0 ”的措辞有点奇怪,我不完全确定它应该传达什么,但是对于 C++11(草案 N3337)data()的返回值在[string.accessors]中进一步指定/1以便对于范围内的data() + i == &operator[](i)所有内容,在[strings.access]/2中指定返回对 a (也称为空字符)的引用,而无需任何条件。i[0,size()]operator[]CharT()operator[](size())

2018 年,奇怪的措辞也通过编辑更改被替换,请参阅https://github.com/cplusplus/draft/pull/1879