Skip to content

Instantly share code, notes, and snippets.

@ahundt
Created March 17, 2015 23:48
Show Gist options
  • Save ahundt/7cad089bb7960ca987c1 to your computer and use it in GitHub Desktop.
Save ahundt/7cad089bb7960ca987c1 to your computer and use it in GitHub Desktop.
rvalue reference to boost asio completion handler
// Library includes
#include <string>
#include <ostream>
#include <iostream>
#include <memory>
#include <vector>
#include <iostream>
// Boost includes
#include <boost/array.hpp>
#include <boost/asio.hpp>
#include <boost/lexical_cast.hpp>
enum { max_length = 1024 };
struct dummy{};
struct SocketTest : std::enable_shared_from_this<SocketTest> {
SocketTest(boost::asio::ip::udp::socket socket):socket_(std::move(socket)){}
template<typename Handler>
void async_receive(dummy dummy,Handler&& handler){
auto self(shared_from_this());
socket_.async_receive(boost::asio::buffer(buf_), std::bind([this,self](boost::system::error_code ec, std::size_t bytes_transferred, Handler&& moved_handler){
moved_handler(ec,bytes_transferred);
}, std::move(handler)));
}
std::array<char,max_length> buf_;
boost::asio::ip::udp::socket socket_;
};
int main(int argc, char* argv[])
{
try
{
std::string localhost("192.170.10.100");
std::string localport("30200");
std::string remotehost("192.170.10.2");
std::string remoteport("30200");
std::cout << "argc: " << argc << "\n";
/// @todo add default localhost/localport
if (argc !=5 && argc !=1)
{
std::cerr << "Usage: " << argv[0] << " <localip> <localport> <remoteip> <remoteport>\n";
return 1;
}
if(argc ==5){
localhost = std::string(argv[1]);
localport = std::string(argv[2]);
remotehost = std::string(argv[3]);
remoteport = std::string(argv[4]);
}
std::cout << "using: " << argv[0] << " " << localhost << " " << localport << " " << remotehost << " " << remoteport << "\n";
boost::asio::io_service io_service;
boost::asio::ip::udp::socket s(io_service, boost::asio::ip::udp::endpoint(boost::asio::ip::address::from_string(localhost), boost::lexical_cast<short>(localport)));
boost::asio::ip::udp::resolver resolver(io_service);
boost::asio::ip::udp::endpoint endpoint = *resolver.resolve({boost::asio::ip::udp::v4(), remotehost, remoteport});
s.connect(endpoint);
SocketTest socket_test(std::move(s));
socket_test.async_receive(dummy(), []( boost::system::error_code ec, std::size_t bytes_transferred){
// many cool things accomplished!
});
}
catch (std::exception& e)
{
std::cerr << "Exception: " << e.what() << "\n";
}
return 0;
}
± make asioSocketTest
[100%] Building CXX object test/CMakeFiles/asioSocketTest.dir/asioSocketTest.cpp.o
In file included from /Users/athundt/source/robone/test/asioSocketTest.cpp:12:
In file included from /usr/local/include/boost/asio.hpp:21:
/usr/local/include/boost/asio/basic_datagram_socket.hpp:710:5: error: static_assert failed
"ReadHandler type requirements not met"
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/local/include/boost/asio/detail/handler_type_requirements.hpp:153:3: note: expanded from
macro 'BOOST_ASIO_READ_HANDLER_CHECK'
BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT( \
^
/usr/local/include/boost/asio/detail/handler_type_requirements.hpp:105:6: note: expanded from
macro 'BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT'
static_assert(expr, msg);
^
/Users/athundt/source/robone/test/asioSocketTest.cpp:29:13: note: in instantiation of function
template specialization 'boost::asio::basic_datagram_socket<boost::asio::ip::udp,
boost::asio::datagram_socket_service<boost::asio::ip::udp>
>::async_receive<boost::asio::mutable_buffers_1, std::__1::__bind<<lambda at
/Users/athundt/source/robone/test/asioSocketTest.cpp:29:64>, <lambda at
/Users/athundt/source/robone/test/asioSocketTest.cpp:77:40> > >' requested here
socket_.async_receive(boost::asio::buffer(buf_), std::bind([this,self](boost::system::...
^
/Users/athundt/source/robone/test/asioSocketTest.cpp:77:17: note: in instantiation of function
template specialization 'SocketTest::async_receive<<lambda at
/Users/athundt/source/robone/test/asioSocketTest.cpp:77:40> >' requested here
socket_test.async_receive(dummy(), []( boost::system::error_code ec, std::size_t bytes...
^
In file included from /Users/athundt/source/robone/test/asioSocketTest.cpp:12:
In file included from /usr/local/include/boost/asio.hpp:21:
/usr/local/include/boost/asio/basic_datagram_socket.hpp:710:5: error: no matching function for
call to object of type 'std::__1::__bind<<lambda at
/Users/athundt/source/robone/test/asioSocketTest.cpp:29:64>, <lambda at
/Users/athundt/source/robone/test/asioSocketTest.cpp:77:40> >'
BOOST_ASIO_READ_HANDLER_CHECK(ReadHandler, handler) type_check;
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/local/include/boost/asio/detail/handler_type_requirements.hpp:167:9: note: expanded from
macro 'BOOST_ASIO_READ_HANDLER_CHECK'
boost::asio::detail::lvref< \
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/functional:2083:9: note:
candidate template ignored: substitution failure [with _Args = <const
boost::system::error_code &, const unsigned long &>]: implicit instantiation of undefined
template 'std::__1::__bind_return<<lambda at
/Users/athundt/source/robone/test/asioSocketTest.cpp:29:64>, std::__1::tuple<<lambda at
/Users/athundt/source/robone/test/asioSocketTest.cpp:77:40> >, std::__1::tuple<const
boost::system::error_code &, const unsigned long &>, false>'
operator()(_Args&& ...__args)
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/functional:2092:9: note:
candidate template ignored: substitution failure [with _Args = <const
boost::system::error_code &, const unsigned long &>]: implicit instantiation of undefined
template 'std::__1::__bind_return<const <lambda at
/Users/athundt/source/robone/test/asioSocketTest.cpp:29:64>, const std::__1::tuple<<lambda
at /Users/athundt/source/robone/test/asioSocketTest.cpp:77:40> >, std::__1::tuple<const
boost::system::error_code &, const unsigned long &>, false>'
operator()(_Args&& ...__args) const
^
In file included from /Users/athundt/source/robone/test/asioSocketTest.cpp:12:
In file included from /usr/local/include/boost/asio.hpp:21:
In file included from /usr/local/include/boost/asio/basic_datagram_socket.hpp:20:
In file included from /usr/local/include/boost/asio/basic_socket.hpp:20:
In file included from /usr/local/include/boost/asio/basic_io_object.hpp:19:
In file included from /usr/local/include/boost/asio/io_service.hpp:24:
In file included from /usr/local/include/boost/asio/detail/wrapped_handler.hpp:18:
/usr/local/include/boost/asio/detail/bind_handler.hpp:127:5: error: no matching function for call
to object of type 'std::__1::__bind<<lambda at
/Users/athundt/source/robone/test/asioSocketTest.cpp:29:64>, <lambda at
/Users/athundt/source/robone/test/asioSocketTest.cpp:77:40> >'
handler_(static_cast<const Arg1&>(arg1_),
^~~~~~~~
/usr/local/include/boost/asio/handler_invoke_hook.hpp:69:3: note: in instantiation of member
function 'boost::asio::detail::binder2<std::__1::__bind<<lambda at
/Users/athundt/source/robone/test/asioSocketTest.cpp:29:64>, <lambda at
/Users/athundt/source/robone/test/asioSocketTest.cpp:77:40> >, boost::system::error_code,
unsigned long>::operator()' requested here
function();
^
/usr/local/include/boost/asio/detail/handler_invoke_helpers.hpp:37:3: note: in instantiation of
function template specialization
'boost::asio::asio_handler_invoke<boost::asio::detail::binder2<std::__1::__bind<<lambda at
/Users/athundt/source/robone/test/asioSocketTest.cpp:29:64>, <lambda at
/Users/athundt/source/robone/test/asioSocketTest.cpp:77:40> >, boost::system::error_code,
unsigned long> >' requested here
asio_handler_invoke(function, boost::asio::detail::addressof(context));
^
/usr/local/include/boost/asio/detail/reactive_socket_recv_op.hpp:110:42: note: in instantiation of
function template specialization
'boost_asio_handler_invoke_helpers::invoke<boost::asio::detail::binder2<std::__1::__bind<<lambda
at /Users/athundt/source/robone/test/asioSocketTest.cpp:29:64>, <lambda at
/Users/athundt/source/robone/test/asioSocketTest.cpp:77:40> >, boost::system::error_code,
unsigned long>, std::__1::__bind<<lambda at
/Users/athundt/source/robone/test/asioSocketTest.cpp:29:64>, <lambda at
/Users/athundt/source/robone/test/asioSocketTest.cpp:77:40> > >' requested here
boost_asio_handler_invoke_helpers::invoke(handler, handler.handler_);
^
/usr/local/include/boost/asio/detail/reactive_socket_recv_op.hpp:79:51: note: in instantiation of
member function
'boost::asio::detail::reactive_socket_recv_op<boost::asio::mutable_buffers_1,
std::__1::__bind<<lambda at /Users/athundt/source/robone/test/asioSocketTest.cpp:29:64>,
<lambda at /Users/athundt/source/robone/test/asioSocketTest.cpp:77:40> > >::do_complete'
requested here
buffers, flags, &reactive_socket_recv_op::do_complete),
^
/usr/local/include/boost/asio/detail/reactive_socket_service_base.hpp:283:21: note: in
instantiation of member function
'boost::asio::detail::reactive_socket_recv_op<boost::asio::mutable_buffers_1,
std::__1::__bind<<lambda at /Users/athundt/source/robone/test/asioSocketTest.cpp:29:64>,
<lambda at /Users/athundt/source/robone/test/asioSocketTest.cpp:77:40> >
>::reactive_socket_recv_op' requested here
p.p = new (p.v) op(impl.socket_, impl.state_, buffers, flags, handler);
^
/usr/local/include/boost/asio/datagram_socket_service.hpp:384:19: note: in instantiation of
function template specialization
'boost::asio::detail::reactive_socket_service_base::async_receive<boost::asio::mutable_buffers_1,
std::__1::__bind<<lambda at /Users/athundt/source/robone/test/asioSocketTest.cpp:29:64>,
<lambda at /Users/athundt/source/robone/test/asioSocketTest.cpp:77:40> > >' requested here
service_impl_.async_receive(impl, buffers, flags, init.handler);
^
/usr/local/include/boost/asio/basic_datagram_socket.hpp:712:32: note: in instantiation of function
template specialization
'boost::asio::datagram_socket_service<boost::asio::ip::udp>::async_receive<boost::asio::mutable_buffers_1,
std::__1::__bind<<lambda at /Users/athundt/source/robone/test/asioSocketTest.cpp:29:64>,
<lambda at /Users/athundt/source/robone/test/asioSocketTest.cpp:77:40> > >' requested here
return this->get_service().async_receive(this->get_implementation(),
^
/Users/athundt/source/robone/test/asioSocketTest.cpp:29:13: note: in instantiation of function
template specialization 'boost::asio::basic_datagram_socket<boost::asio::ip::udp,
boost::asio::datagram_socket_service<boost::asio::ip::udp>
>::async_receive<boost::asio::mutable_buffers_1, std::__1::__bind<<lambda at
/Users/athundt/source/robone/test/asioSocketTest.cpp:29:64>, <lambda at
/Users/athundt/source/robone/test/asioSocketTest.cpp:77:40> > >' requested here
socket_.async_receive(boost::asio::buffer(buf_), std::bind([this,self](boost::system::...
^
/Users/athundt/source/robone/test/asioSocketTest.cpp:77:17: note: in instantiation of function
template specialization 'SocketTest::async_receive<<lambda at
/Users/athundt/source/robone/test/asioSocketTest.cpp:77:40> >' requested here
socket_test.async_receive(dummy(), []( boost::system::error_code ec, std::size_t bytes...
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/functional:2083:9: note:
candidate template ignored: substitution failure [with _Args = <const
boost::system::error_code &, const unsigned long &>]: implicit instantiation of undefined
template 'std::__1::__bind_return<<lambda at
/Users/athundt/source/robone/test/asioSocketTest.cpp:29:64>, std::__1::tuple<<lambda at
/Users/athundt/source/robone/test/asioSocketTest.cpp:77:40> >, std::__1::tuple<const
boost::system::error_code &, const unsigned long &>, false>'
operator()(_Args&& ...__args)
^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/functional:2092:9: note:
candidate template ignored: substitution failure [with _Args = <const
boost::system::error_code &, const unsigned long &>]: implicit instantiation of undefined
template 'std::__1::__bind_return<const <lambda at
/Users/athundt/source/robone/test/asioSocketTest.cpp:29:64>, const std::__1::tuple<<lambda
at /Users/athundt/source/robone/test/asioSocketTest.cpp:77:40> >, std::__1::tuple<const
boost::system::error_code &, const unsigned long &>, false>'
operator()(_Args&& ...__args) const
^
3 errors generated.
make[3]: *** [test/CMakeFiles/asioSocketTest.dir/asioSocketTest.cpp.o] Error 1
make[2]: *** [test/CMakeFiles/asioSocketTest.dir/all] Error 2
make[1]: *** [test/CMakeFiles/asioSocketTest.dir/rule] Error 2
make: *** [asioSocketTest] Error 2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment