【问题标题】:Boost asio ConstBufferSequence - c++ TemplatesBoost asio ConstBufferSequence - c++ 模板
【发布时间】:2011-09-06 08:32:28
【问题描述】:

我希望获得有关 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::asio::buffer 类型的缓冲区包装在我的boost::array 对象周围。这工作正常,但现在我想在相反的方向工作。也就是说,我想写回套接字,从我已经拥有的一些自定义存储类中提取数据。 我的问题是,我如何理解 boost::asio::buffer 或更一般地由以下指定的参数类型所要求的模板类型要求:

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

API 列出了ConstBufferSequence 的要求,但我无法对此做出正面或反面。有人可以帮我理解吗?我要传递给“发送”函数的类型需要公开哪些方法?

【问题讨论】:

    标签: c++ templates boost boost-asio


    【解决方案1】:

    boost::asio::buffer 返回实现ConstBufferSequenceMutableBufferSequence 概念的对象;它不期望 来实现它们。您可以传递给buffer 的具体类型列在here

    【讨论】:

    • 不完全是我想要的,但让事情变得更加清晰。感谢您的回答。 :)
    【解决方案2】:

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

    [如果 Concepts 已将其纳入标准 [叹气],您将需要一个实现 ConstBufferSequence 概念的对象]

    下面是 QuickFAST (http:://www.quickfast.org) 中 Codecs::DataDestination 类的代码片段,它实现了 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_);
      }
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多