2011-06-01 166 views
5

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

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对象。这工作正常,但现在我想反向工作。也就是说,我想重新写入套接字,从我已有的一些自定义存储类中提取数据。 我的问题是,如何使所需要的模板类型要求的意义是通过升压:: ASIO ::缓冲,或者更一般的可缠绕,参数类型由指定:

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

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

回答

4

boost::asio::buffer返回实现ConstBufferSequenceMutableBufferSequence概念的对象;它并不期望来执行它们。您被允许传递给buffer的具体类型列出为here

+0

不完全是我想要的,但让事情变得更清晰。感谢你的回答。 :) – 2011-06-01 20:44:22

0

虽然升压:: ASIO ::缓冲工程确定,如果你有一组连续的,你想作为缓冲来使用,如果使用的是分散在内存字节/聚集I/O --or特别是如果你正在使用聚集写入(分散读取不太常见),您需要拥有一个类似于ConstBufferSequence的对象。

[如果概念已经使它成为标准[叹息],您将需要一个实现ConstBufferSequence概念的对象]

这里是从编解码器:: DataDestination类代码QuickFAST(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_); 
    } 
};