2015-02-12 18 views
6

Próbuję użyć wersji Asio w wersji Non Boost w projekcie. Piszę wywołanie zwrotne do stream_protocol::acceptor::async_accept. Podpis wymaga asio::placeholders::error być przekazywane, ale kiedy to zrobić, pojawia się następujący błąd:Nie można użyć asio :: placeholders :: błąd w niekompatybilnej wersji Asio

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

Następujące źródła, widzę błąd istnieje, ale od rodzaju undefined, który jest dla mnie nowe. Czy czegoś brakuje? Czy mam przeprowadzić wstępne przetwarzanie bibliotek?

Odpowiedz

13

W skrócie, użyj std::placeholders::_1 zamiast asio::placeholders:error.


Asio obsługuje tylko wygodne zmienne zastępcze podczas korzystania z funkcji Boost.Bind. W error zastępczy documentation stany:

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

Podczas korzystania std::bind() stworzyć koparki, trzeba użyć std::bind „s zastępcze. Operacja async_accept() przyjmuje obsługi, która spełnia wymagania AcceptHandler TYP:

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 .

Tworząc funktorem z std::bind() funkcjonować jako AcceptHandler, jeśli chce się uzyskać error_code argumentu, a następnie za pomocą std::placeholders::_1:

void handle_accept(const std::error_code&); 

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

Oto kompletny minimalny przykład demonstrating przy użyciu std::bind(). Zauważ, że coliru nie wydaje się mieć wersja Asio samodzielna dostępny, ale przykład powinny wystarczyć:

#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(); 
} 

wyjściowa:

handle_accept: Success 

Ewentualnie, jeśli ktoś chce do nieco bardziej szczegółowość, a następnie nazwane zastępczych mogą być stosowane:

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

// ... 

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

typu I obserwuje unspecified n kod źródłowy jest używany tylko podczas generowania dokumentacji, jak pokazano w tym 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

Alternatywnie przy korzystaniu Boost.Bind z non-asio rozkwit trzeba zdefiniować 'ASIO_HAS_BOOST_BIND' uzyskać zastępcze wygody. – robsn

Powiązane problemy