Is there a more efficient way to set a std::vector from a stream?

WilliamKF picture WilliamKF · May 30, 2012 · Viewed 7.6k times · Source

Presently, I set the value of a std::vector<char> from an std::ostringstream as follows:

void
foo(std::vector<char> &data, std::stringstream &stream) {
  data = std::vector<char>(stream.str().begin(), stream.str().end());
}

I'm wondering if there is a more efficient way to do this with STL in C++ or whether the method I give here is considered appropriate? Would I be better off using std::stringstream instead?

Answer

K-ballo picture K-ballo · May 30, 2012

As pointed out in comments, your code is incorrect due to the two calls to str(). In order to improve efficiency you can avoid creating a temporary vector, like this:

void foo(std::vector<char> &data, std::stringstream &stream) {
    const std::string& str = stream.str();
    data.assign( str.begin(), str.end() );
}

You can also avoid the std::string by using std::istreambuf_iterators:

void foo(std::vector<char> &data, std::stringstream &stream) {
    data.assign(
        std::istreambuf_iterator<char>( stream ), std::istreambuf_iterator<char>()
    );
}

but given that those are input iterators, the vector has no chance to know how much data will be assigned and could perform a bit worse, as it cannot reserve enough space to avoid reallocations.