使用std :: string与C风格API交互时,是否可以避免使用临时缓冲区?

Ben*_*enj 8 c c++

我应该在这个问题前面说我认为答案可能不是,但我想看看其他人对这个问题的看法.

我花了大部分时间编写与Win32 API交互的C++,就像大多数C风格API想要的那样:

  1. 拿我提供的缓冲液并对它们进行操作.
  2. 或者返回指向我需要稍后释放的缓冲区的指针.

这两种情况本质上都意味着如果你想std::string在你的代码中使用,你必须接受这样一个事实,即你每次std::string从临时缓冲区构造一个字符串时都会进行大量的字符串复制.

什么会很好:

  1. 能够允许C风格API安全地直接改变std::string并预先保留其分配并提前设置其大小(以缓解方案1)
  2. 能够包裹std::string现有的char[](以缓解方案2)

有没有一种很好的方法来做其中任何一种,或者我应该接受使用std::string旧学校API 的固有成本?看起来情况1看起来特别棘手,因为它std::string有一个短的字符串优化,因此它的缓冲区可以在堆栈或堆上,具体取决于它的大小.

Lig*_*ica 10

在C++ 11中,您可以简单地将指针传递给string(&str[0])的第一个元素:它的元素保证是连续的.

以前,您可以使用.data().c_str()但字符串不可通过这些.

否则,是的,您必须执行副本.但是我不会太担心这个,直到分析表明这对你来说真的是一个问题.

  • 为什么这会被贬低?您当然可以写入`&str [0]`或指向它的指针.`operator []`作为const和非const重载.`reserve`允许你做它的名字所说的内容,`resize`允许你将长度截断为C API函数报告之后写的字符数.此外,分配的内存保证是连续的.为什么这不起作用? (4认同)
  • @Tomalak:一个小问题 - `str [str.size()]`返回对0终止符的引用,但是对于非空字符串,它是保证的,`(&str [str.size() - 1]) + 1`指向0终止符?字符串在21.4.1/5处的连续性要求的文本(它表示`<s.size()`,而不是`<= s.size()`)表明0终止符*不是*必然是缓冲区,因此`&str [0]`仅在所讨论的C风格API需要长度而不是寻找nul时才有效.即使`str`没有嵌入的nuls也是如此. (2认同)
  • @Tomalak OCD对此非常强大.;-) (2认同)