有没有办法获得std:string的缓冲区

Mik*_*Mik 14 c++ winapi stl stdstring

有没有办法获得"原始"缓冲区oa std :: string?
我在想类似的东西CString::GetBuffer().例如,使用CString我会这样做:

CString myPath;  
::GetCurrentDirectory(MAX_PATH+1, myPath.GetBuffer(MAX_PATH));  
myPath.ReleaseBuffer();  
Run Code Online (Sandbox Code Playgroud)

那么,std :: string有类似的东西吗?

Xeo*_*Xeo 17

std::vector<char>如果需要真正的缓冲区,请使用.

#include <vector>
#include <string>

int main(){
  std::vector<char> buff(MAX_PATH+1);
  ::GetCurrentDirectory(MAX_PATH+1, &buff[0]);
  std::string path(buff.begin(), buff.end());
}
Run Code Online (Sandbox Code Playgroud)

Ideone上的示例.

  • 如果你使用std :: vector作为*buffer*,你最终会以最昂贵的方式初始化向量中的每个**元素**.这将使整个应用程序中的任何CPU成本相形见绌.使用`std :: unique_ptr <char []>`或堆栈分配.如果不需要,不要在初始化缓冲区时浪费CPU. (3认同)
  • @DeadMG我只是根据经验说话,通过分析器运行你的程序并自己检查,但你显然需要超过1次调用才能成为瓶颈.我提出这个问题的原因是因为如果你把它放在你经常调用的库例程中,你就会浪费很多CPU.此外,由于您在编译时知道MAX_PATH,因此可能是堆栈分配,该缓冲区的持续时间很可能非常短.无论如何,向量类代表*真实缓冲区*的概念完全是错误的. (3认同)
  • @JohnLeidegren:内核切换到 GetCurrentDirectory 可能更昂贵。您需要的不仅仅是 1 个以上的调用,而是大量的调用,这才会成为瓶颈。您的评论暗示这可能是一个严重的问题,而事实上它不太可能成为一个问题。 (2认同)

Joh*_*ren 17

虽然有点非正统,但std::string用作线性内存缓冲区是完全有效的,唯一需要注意的是,在C++ 11之前,标准不支持它.

std::string s;
char* s_ptr = &s[0]; // get at the buffer
Run Code Online (Sandbox Code Playgroud)

引用Herb Sutter,

我知道的每个std :: string实现实际上都是连续的并且null终止它的缓冲区.所以,虽然它没有得到正式的保证,但实际上你可以通过调用&str [0]来获取指向连续和以null结尾的字符串的指针.(但为了安全起见,你仍然应该使用str.c_str().)

可能是关键在这里.因此,虽然它不是一个保证,但您应该能够依赖于std::string线性内存缓冲区的原则,并且您应该在测试套件中断言关于此的事实,只是为了确定.

你可以随时建立自己的缓冲类,但是当你想购买时,这就是STL提供的.

  • str.c_str() 返回一个 const 指针,这肯定是一样的,如果不是更危险的话 (2认同)