2015-02-12 11 views
6

Sto provando a utilizzare la versione non Boost di Asio in un progetto. Sto scrivendo una richiamata a stream_protocol::acceptor::async_accept. La firma richiede asio::placeholders::error per essere passato, ma quando lo faccio, ottengo il seguente errore:Impossibile utilizzare asio :: segnaposti :: errore nella versione non Boost di Asio

error: no member named 'error' in namespace 'asio::placeholders'

In seguito alla fonte, posso vedere l'errore è lì, ma di tipo undefined, che è nuovo per me. Mi sto perdendo qualcosa? Dovrei fare una sorta di pre-elaborazione delle librerie?

risposta

13

In breve, utilizzare std::placeholders::_1 anziché asio::placeholders:error.


Asio supporta solo le convenienti variabili segnaposto quando si utilizza Boost.Bind. I segnaposto errordocumentation stati:

An argument placeholder, for use with boost::bind(), ...

Quando si utilizza std::bind() per creare i gestori, si ha la necessità di utilizzare std::bind s' segnaposto. L'operazione async_accept() accetta un gestore che soddisfi i requisiti AcceptHandler tipo:

An accept handler must meet the requirements for a handler. A value h of an accept handler class should work correctly in the expression h(ec) , where ec is an lvalue of type const error_code .

Quando si crea un funtore con std::bind() per funzionare come un AcceptHandler, se si vuole ottenere l'argomento error_code, quindi utilizzare std::placeholders::_1:

void handle_accept(const std::error_code&); 

acceptor.async_accept(server_socket, std::bind(&handle_accept, 
    std::placeholders::_1 /* error_code */)); 

Ecco un esempio minimale completo demonstrating utilizzando std::bind(). Si noti che coliru non sembra avere una versione Asio standalone a disposizione, ma l'esempio dovrebbe essere sufficiente:

#include <iostream> 
#include <functional> 

#include <boost/asio.hpp> 

void handle_accept(const boost::system::error_code& error_code) 
{ 
    std::cout << "handle_accept: " << error_code.message() << std::endl; 
} 

void noop() {} 

int main() 
{ 
    using boost::asio::ip::tcp; 
    boost::asio::io_service io_service; 

    // Create all I/O objects. 
    tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 0)); 
    tcp::socket server_socket(io_service); 
    tcp::socket client_socket(io_service); 

    // Connect client and server sockets. 
    acceptor.async_accept(server_socket, std::bind(&handle_accept, 
    std::placeholders::_1 /* error_code */)); 
    client_socket.async_connect(acceptor.local_endpoint(), std::bind(&noop)); 
    io_service.run(); 
} 

uscita:

handle_accept: Success 

facoltativamente, se si vuole un po 'più di dettaglio, poi denominati segnaposto potrebbe essere utilizzato:

namespace asio_placeholders 
{ 
    auto error = std::placeholders::_1; 
} 

// ... 

acceptor.async_accept(server_socket, std::bind(&handle_accept, 
    asio_placeholders::error)); 

Il tipo unspecified osservato i n il codice sorgente viene utilizzato solo durante la generazione di documentazione, come mostrato in questo code:

#if defined(GENERATING_DOCUMENTATION) 

/// An argument placeholder, for use with boost::bind(), that corresponds to 
/// the error argument of a handler for any of the asynchronous functions. 
unspecified error; 

// ... 

#elseif 
+0

alternativa quando si utilizza Boost.Bind con i non-boost Asio è necessario definire 'ASIO_HAS_BOOST_BIND' per ottenere i segnaposto di convenienza. – robsn