所以istringstream
在初始化时复制字符串的内容,例如
string moo("one two three four");
istringstream iss(moo.c_str());
我想知道是否有办法让std::istringstream
使用给定的c_str
作为缓冲区而不复制内容。这样,在将std::istringstream&
传递给以istream&
为参数的函数之前,不必复制大量内存。
我一直在尝试将一些仅将std::ifstream&
个参数(它们主要是解析器)的函数转换为istream&
。我是否必须为此创建自己的istream
子类?
答案 0 :(得分:5)
使用istringstream
并不是一个令人满意的解决方案,因为这会复制整个缓冲区。
之前的回答显示已弃用istrstream
,但由于这会生成警告并且将来可能会被删除,因此更好的解决方案是使用boost::iostreams:
boost::iostreams::stream<boost::iostreams::array_source> stream(moo.c_str(), moo.size());
这样可以避免以istrstream
相同的方式复制缓冲区,并且可以节省您编写自己的流类的时间。
答案 1 :(得分:3)
已弃用的istrstream
支持此功能。
#include <string>
#include <strstream>
using namespace std;
int main(int argc, char* argv[])
{
string moo = "one two three four";
istrstream istr(const_cast<char*>(moo.c_str()),moo.size());
std::string line;
while(!istr.fail() && !istr.eof()){
getline(istr,line,' ');
cout << line << "_";
}
// prints: one_two_three_four_
}
答案 2 :(得分:3)
编写一个从给定内存区域读取的基本std::streambuf
类是相当简单的。然后,您可以从中构造istream
并从中读取。
initializing a C++ std::istringstream from an in memory buffer?
请注意,指向c_str()
的缓冲区的生命周期非常有限,并且无法保证对c_str()
的调用会导致某些复制,尽管我不知道任何实现它在哪里。
答案 3 :(得分:2)
只有一个副本,因为您传递的参数const char*
需要转换为istringstream constructor的参数类型。
只需传递string
而无需致电c_str()
。
istringstream iss(moo);
好吧,这并不能完全阻止复制,但它可以消除不必要的复制。要完全删除副本,您必须重写std::stringbuf
,这样可以避免直接使用您提供的string
。
答案 4 :(得分:2)
这取决于std :: string的作用。根据27.2.1 / 1 The class basic_istringstream<charT,traits,Allocator> ... uses a basic_stringbuf<charT,traits,Allocator> object to control the associated storage.
由于类必须使用对象,因此必须将字符串构造到该对象中。
所以真正的问题不是stringstream
是否复制内容,而是复制构造字符串是复制内容还是实现某种写时复制方案。