efficient copy of data from boost::asio::streambuf

2019-07-21 04:02发布

问题:

I need to copy the content of a (boost::asio::)streambuf to an std::string.

The following code works, but I think that there's an unnecessary copy between _msg and the temporary std::string:

Msg (boost::asio::streambuf & sb, size_t bytes_transferred) :
    _nBytesInMsg    (bytes_transferred)
{
    boost::asio::streambuf::const_buffers_type buf = sb.data();

    _msg = std::string(
        boost::asio::buffers_begin(buf),
        boost::asio::buffers_begin(buf) + _nBytesInMsg);
}

I tried replacing with the following:

     _msg.reserve(_nBytesInMsg);
     std::copy(
        boost::asio::buffers_begin(buf),
        boost::asio::buffers_begin(buf) + _nBytesInMsg,
        _msg.begin()
    );

While this compiles, it doesn't copy anything to the _msg string.

Will the compiler (gcc4.4.7) optimize this case - e.g. copy the streambuf straight to _msg without using a temporary?

Is there perhaps an iterator I can use with boost::asio::streambuf::const_buffers_type in order to make the std::copy work instead?

回答1:

reserve doesn't mean what you think it means. You can work out for sure what it means by reading its documentation. It is not the same as resize; reserving space does not affect the container's size.

You need to actually insert elements into the string. Do this:

#include <algorithm>    // for copy
#include <iterator>     // for back_inserter

_msg.reserve(_nBytesInMsg);  // about to insert _nBytesInMsg elements

std::copy(
    boost::asio::buffers_begin(buf),
    boost::asio::buffers_begin(buf) + _nBytesInMsg,
    std::back_inserter(_msg)
);