2011-06-01 13 views
5

Espero alguna guía con respecto a las plantillas de C++. He estado usando la biblioteca boost::asio para la comunicación a través de TCP. Hasta ahora, he estado utilizando contenedores de almacenamiento integrados en la biblioteca boost :: asio. Por ejemplo:Boost asio ConstBufferSequence - Plantillas de C++

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

para leer desde una toma de corriente, simplemente me envuelvo un búfer de tipo boost::asio::buffer alrededor de mi objeto boost::array. Esto funciona bien, pero ahora me gustaría trabajar en la dirección opuesta. Es decir, me gustaría volver a escribir en el socket, extrayendo datos de algunas clases de almacenamiento personalizadas que ya tengo. Mi pregunta es, ¿cómo puedo hacer sentido de los requisitos del tipo de plantilla necesarios para ser Wrappable por impulso :: :: asio del búfer, o más en general, el tipo de parámetro especificado por:

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

Las listas de la API requisitos de un ConstBufferSequence, pero no puedo entender nada de esto. ¿Alguien puede ayudarme a entender? ¿Qué métodos debería exponer el tipo que quiero pasar a la función "enviar"?

Respuesta

4

boost::asio::buffer devuelve objetos que implementan los conceptos ConstBufferSequence y MutableBufferSequence; no espera usted para implementarlos. Los tipos de concreto que puede pasar al buffer se enumeran en here.

+0

No es exactamente lo que quería, pero dejó las cosas más claras, no obstante. Gracias por la respuesta. :) –

0

Aunque boost :: asio :: buffer funciona bien si tiene un conjunto contiguo de bytes en la memoria que desea usar como buffer, si está utilizando scatter/gather I/O, o en particular si están utilizando las escrituras de recopilación (las lecturas de dispersión son mucho menos comunes), es necesario que tenga un objeto que se comporte como una secuencia de ConstBuffer.

[Si Conceptos habían hecho en la norma [suspiro], se necesitaría un objeto que implementa el concepto ConstBufferSequence]

Aquí es un fragmento de código de la clase :: Codecs DataDestination en QuickFAST (http: : //www.quickfast.org) que implementa 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_); 
    } 
}; 
Cuestiones relacionadas