使用std :: string与C风格API交互时,是否可以避免使用临时缓冲区?
我应该在这个问题前面说我认为答案可能不是,但我想看看其他人对这个问题的看法。
我花了大部分时间编写与Win32 API交互的C ++,就像大多数C风格API想要的那样:
- 拿我提供的缓冲液并对它们进行操作。
- 或者返回指向我需要稍后释放的缓冲区的指针。
这两种情况本质上都意味着如果你想在你的代码中使用std::string
,你必须接受这样一个事实,即你每次从你构造一个std::string
都会进行大量的字符串复制。一个临时缓冲区。
什么会很好:
- 能够允许C风格API安全地直接改变
std::string
并预先保留其分配并提前设置其大小(以缓解方案1) - 能够围绕现有的
char[]
包装std::string
(以缓解方案2)
有没有一种很好的方法来做其中任何一种,或者我应该接受使用std::string
和旧学校API的固有成本? 看起来情况1看起来特别棘手,因为std::string
有一个短的字符串优化,因此它的缓冲区可以在堆栈或堆上,具体取决于它的大小。
在C ++ 11中,您可以简单地将指针传递给字符串的第一个元素( &str[0]
):它的元素保证是连续的。
以前,您可以使用.data()
或.c_str()
但字符串不可通过这些。
否则,是的,您必须执行副本。 但是我不会太担心这个,直到分析表明这对你来说真的是一个问题。
好吧,你可能只是将字符串的.data()
const_cast到char*
,它很可能会工作。 与所有优化一样,确保实际上代码的这一部分是瓶颈。 如果是,请将其包装在内联函数或模板类或其他内容中,以便您可以为其编写一些测试,如果在某些平台上不起作用则更改行为。
我认为你可以安全地使用std ::(w)字符串来做这件事就是将它作为一个输入传递给它的用户不会被修改; 使用.c_str()
获取指向(W)CHAR
的指针。
您也许可以使用std::vector
。 你可以直接将指向第一个字符的指针传递给C代码,然后让C代码写下你不能用字符串做的代码。 你想对std::vector
上的字符串执行的许多操作也是如此。