非复制istringstream

时间:2010-06-26 05:59:14

标签: c++ istream istringstream

所以istringstream在初始化时复制字符串的内容,例如

string moo("one two three four");
istringstream iss(moo.c_str());

我想知道是否有办法让std::istringstream使用给定的c_str作为缓冲区而不复制内容。这样,在将std::istringstream&传递给以istream&为参数的函数之前,不必复制大量内存。

我一直在尝试将一些仅将std::ifstream&个参数(它们主要是解析器)的函数转换为istream&。我是否必须为此创建自己的istream子类?

5 个答案:

答案 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是否复制内容,而是复制构造字符串是复制内容还是实现某种写时复制方案。