Boost asio ConstBufferSequence - c++ Templates

Boost asio ConstBufferSequence - c++ Templates

本文关键字:c++ Templates ConstBufferSequence asio Boost      更新时间:2023-10-16

我希望得到一些关于C++模板的指导。我一直在使用boost::asio库通过TCP进行通信。到目前为止,我一直在使用boost::asio库中内置的存储容器。例如:

boost::array<char, 128> buf;
boost::system::error_code error;
size_t len = socket.read_some(boost::asio::buffer(buf), error);

要从套接字读取,我只需在boost::array对象周围包装一个boost::asio::buffer类型的缓冲区。这很好,但现在我想反其道而行之。也就是说,我想写回套接字,从我已经拥有的一些自定义存储类中提取数据我的问题是,我如何理解需要由boost::asio::buffer包装的模板类型要求,或者更一般地说,由指定的参数类型

template<typename ConstBufferSequence>
std::size_t send(   
   const ConstBufferSequence & buffers
);

API列出了ConstBufferSequence的要求,但我不能对此做任何解释。有人能帮我理解吗?我想传递给"send"函数的类型需要公开哪些方法?

boost::asio::buffer返回实现ConstBufferSequenceMutableBufferSequence概念的对象;它并不期望实现它们。此处列出了允许传递给buffer的具体类型。

尽管boost::asio::buffer在内存中有一组连续的字节要用作缓冲区时工作正常,但如果您使用分散/聚集I/O,或者特别是如果您使用聚集写入(分散读取不太常见),您确实需要有一个行为类似ConstBufferSequence的对象。

【如果Concepts已经成为标准【叹息】,那么您将需要一个实现ConstBufferSequence概念的对象】

以下是QuickFAST(http://www.QuickFAST.org)中实现ConstBufferSequence:的Codecs::DataDestination类的代码片段

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_);
  }
};