Хотя boost :: asio :: buffer работает нормально, если у вас есть непрерывный набор байтов в памяти, который вы хотите использовать в качестве буфера, если вы используете scatter / collect I / O - или, в частности, если вы используетеиспользуя сборку (чтение разброса встречается гораздо реже), вам нужен объект, который ведет себя как ConstBufferSequence.
[Если бы Concepts превратил его в стандарт [sigh], вам нужен объект, реализующий концепцию ConstBufferSequence]
Вот фрагмент кода из класса Codecs :: DataDestinationQuickFAST (http :: //www.quickfast.org), который реализует ConstBufferSequence:
class DataDestination
{
/// @brief Support for asio gather writes: forward iterator through buffers
///
/// The intent is for DataDestination to conform to the asio::ConstBufferSequence concept.
/// This would allow it to be passed directly to the asio::write(v)
/// Note the implication that if asynch writes are used the DataDestination must
/// remain intact until the write completes.
class const_iterator
{
public:
/// @brief construct an iterator pointing into a DataDestination
/// @param destination is the buffer-container
/// @param position is the starting position for the iterator.
const_iterator(const DataDestination & destination, size_t position)
: destination_(destination)
, position_(position)
{
}
/// @brief Point iterator to next buffer (preincrement)
const_iterator & operator ++()
{
if(position_ < destination_.size())
{
++position_;
}
return *this;
}
/// @brief Point iterator to next buffer (postincrement)
const_iterator operator ++(int)
{
const_iterator result(*this);
if(position_ < destination_.size())
{
++position_;
}
return result;
}
/// @brief dereference the iterator to find the actual buffer
boost::asio::const_buffer operator * () const
{
const WorkingBuffer & buffer(destination_[position_]);
return boost::asio::const_buffer(buffer.begin(), buffer.size());
}
/// @brief dereference the iterator to find the actual buffer
boost::asio::const_buffer operator -> () const
{
const WorkingBuffer & buffer(destination_[position_]);
return boost::asio::const_buffer(buffer.begin(), buffer.size());
}
/// @brief compare iterators.
/// @param rhs is the iterator to which this should be compared.
bool operator == (const const_iterator & rhs) const
{
return position_ == rhs.position_;
}
/// @brief compare iterators.
/// @param rhs is the iterator to which this should be compared.
bool operator != (const const_iterator & rhs) const
{
return position_ != rhs.position_;
}
private:
const_iterator & operator=(const_iterator &); // no autogenerated assignment
private:
const DataDestination & destination_;
size_t position_;
};
/// @brief return iterator pointing to the first buffer.
const_iterator begin()const
{
return const_iterator(*this, 0);
}
/// @brief return iterator pointing past the last buffer
const_iterator end() const
{
return const_iterator(*this, used_);
}
};