5

In an application using C++11 and Boost.Asio, I came to use lambda functions and an std::unique_ptr. I want to transfer the ownership of this unique_ptr to a lambda. You can't capture the unique_ptr by value as this class doesn't provide a copy constructor. It is also silly to capture it by reference, as I do want the transfer of ownership.

I decided to use std::bind to pass this unique_ptr as a last parameter of this lambda function. I use std::move to give an r-value reference to this lambda. Later I will move this r-value into a std::unique_ptr (local to the lambda). I am stuck with some horrible gcc errors, and wonder what I missed in my code.

Here is the code that contains my ugly non-working trick:

void NetworkClient::start()
{
    // Avoid the naggle algorithm on packets.
    ip::tcp::no_delay optionNoDelay(true);
    socket_.set_option(optionNoDelay);

    // Lambda function that receive a packet header.
    std::function<void (const boost::system::error_code& error, std::size_t bytesTransfered)> receiveHeaderHandler =
    [this, &receiveHeaderHandler] (const boost::system::error_code& error, std::size_t bytesTransfered)
    {
        if (error)
        {
            std::cout << LogType::ERROR << "Error while receiving a packet header" << std::endl;
        }

        if (bytesTransfered < 6)
        {
            std::cout << LogType::ERROR << "Invalid packet received: header size < 6" << std::endl;
        }

        std::cout << "Packet received" << std::endl;

        // Allocate memory for the incoming packet body.
        std::unique_ptr<char[]> packetBody(new char[currentHeader_.size()]);

        // Let's receive the packet body according to the header.
        socket_.async_receive(buffer(packetBody.get(), currentHeader_.size()), std::bind
        ([this, &receiveHeaderHandler] (boost::system::error_code const & error, std::size_t bytesTransfered, std::unique_ptr<char[]> && arg)
        {            
            if (error)
            {
                std::cout << LogType::ERROR << "Error while receiving a packet header" << std::endl;
            }

            if (bytesTransfered < currentHeader_.size())
            {
                std::cout << LogType::ERROR << "Invalid packet received: size of packet < size from header" << std::endl;
            }

            std::unique_ptr<char[]> packetBody(arg);     

            socket_.async_receive(buffer(currentHeader_.data(), 6), receiveHeaderHandler);
         }, std::placeholders::_1, std::placeholders::_2, std::move(packetBody)));
    };

    socket_.async_receive(buffer(currentHeader_.data(), 6), receiveHeaderHandler);
}

Here is the trimmed and cleaned buggy part:

        // Allocate memory for the incoming packet body.
        std::unique_ptr<char[]> packetBody(new char[20]);

        // Let's receive the packet body according to the header.
        socket_.async_receive(asio::buffer(packetBody.get(), 20), std::bind(
        [] (boost::system::error_code const & error, std::size_t bytesTransfered, std::unique_ptr<char[]> && arg)
        {
            std::unique_ptr<char[]> packetBody(arg);

        }, std::placeholders::_1, std::placeholders::_2, std::move(packetBody)));

In this code:

  • packetBody is the std::unique_ptr i want to transfer
  • the async_receive handler must looks like void handler(const boost::system::error_code& error,std::size_t bytes_transferred);
  • the design looks ugly but i wanted to try c++11 lambdas in depth

Here is my gcc output:

In file included from /usr/include/boost/asio.hpp:30:0,
                 from server/network/./network-client.hpp:4,
                 from server/network/network-client.cpp:1:
/usr/include/boost/asio/basic_stream_socket.hpp: In instantiation of 'void boost::asio::basic_stream_socket<Protocol, StreamSocketService>::async_receive(const MutableBufferSequence&, ReadHandler&&) [with MutableBufferSequence = boost::asio::mutable_buffers_1; ReadHandler = std::_Bind<oroshi::network::NetworkClient::start()::<lambda(const boost::system::error_code&, std::size_t)>::<lambda(const boost::system::error_code&, std::size_t, std::unique_ptr<char []>&)>(std::_Placeholder<1>, std::_Placeholder<2>, std::unique_ptr<char []>)>; Protocol = boost::asio::ip::tcp; StreamSocketService = boost::asio::stream_socket_service<boost::asio::ip::tcp>]':
server/network/network-client.cpp:56:70:   required from here
/usr/include/boost/asio/basic_stream_socket.hpp:518:64: error: use of deleted function 'std::_Bind<_Functor(_Bound_args ...)>::_Bind(const std::_Bind<_Functor(_Bound_args ...)>&) [with _Functor = oroshi::network::NetworkClient::start()::<lambda(const boost::system::error_code&, std::size_t)>::<lambda(const boost::system::error_code&, std::size_t, std::unique_ptr<char []>&)>; _Bound_args = {std::_Placeholder<1>, std::_Placeholder<2>, std::unique_ptr<char [], std::default_delete<char []> >}; std::_Bind<_Functor(_Bound_args ...)> = std::_Bind<oroshi::network::NetworkClient::start()::<lambda(const boost::system::error_code&, std::size_t)>::<lambda(const boost::system::error_code&, std::size_t, std::unique_ptr<char []>&)>(std::_Placeholder<1>, std::_Placeholder<2>, std::unique_ptr<char []>)>]'
In file included from /usr/include/boost/system/error_code.hpp:23:0,
                 from /usr/include/boost/asio/io_service.hpp:25,
                 from /usr/include/boost/asio/basic_io_object.hpp:19,
                 from /usr/include/boost/asio/basic_socket.hpp:19,
                 from /usr/include/boost/asio/basic_datagram_socket.hpp:20,
                 from /usr/include/boost/asio.hpp:20,
                 from server/network/./network-client.hpp:4,
                 from server/network/network-client.cpp:1:
/usr/include/c++/4.7/functional:1199:7: note: 'std::_Bind<_Functor(_Bound_args ...)>::_Bind(const std::_Bind<_Functor(_Bound_args ...)>&) [with _Functor = oroshi::network::NetworkClient::start()::<lambda(const boost::system::error_code&, std::size_t)>::<lambda(const boost::system::error_code&, std::size_t, std::unique_ptr<char []>&)>; _Bound_args = {std::_Placeholder<1>, std::_Placeholder<2>, std::unique_ptr<char [], std::default_delete<char []> >}; std::_Bind<_Functor(_Bound_args ...)> = std::_Bind<oroshi::network::NetworkClient::start()::<lambda(const boost::system::error_code&, std::size_t)>::<lambda(const boost::system::error_code&, std::size_t, std::unique_ptr<char []>&)>(std::_Placeholder<1>, std::_Placeholder<2>, std::unique_ptr<char []>)>]' is implicitly deleted because the default definition would be ill-formed:
/usr/include/c++/4.7/functional:1199:7: error: use of deleted function 'constexpr std::tuple< <template-parameter-1-1> >::tuple(const std::tuple< <template-parameter-1-1> >&) [with _Elements = {std::_Placeholder<1>, std::_Placeholder<2>, std::unique_ptr<char [], std::default_delete<char []> >}; std::tuple< <template-parameter-1-1> > = std::tuple<std::_Placeholder<1>, std::_Placeholder<2>, std::unique_ptr<char [], std::default_delete<char []> > >]'
In file included from /usr/include/c++/4.7/functional:56:0,
                 from /usr/include/boost/system/error_code.hpp:23,
                 from /usr/include/boost/asio/io_service.hpp:25,
                 from /usr/include/boost/asio/basic_io_object.hpp:19,
                 from /usr/include/boost/asio/basic_socket.hpp:19,
                 from /usr/include/boost/asio/basic_datagram_socket.hpp:20,
                 from /usr/include/boost/asio.hpp:20,
                 from server/network/./network-client.hpp:4,
                 from server/network/network-client.cpp:1:
/usr/include/c++/4.7/tuple:393:17: note: 'constexpr std::tuple< <template-parameter-1-1> >::tuple(const std::tuple< <template-parameter-1-1> >&) [with _Elements = {std::_Placeholder<1>, std::_Placeholder<2>, std::unique_ptr<char [], std::default_delete<char []> >}; std::tuple< <template-parameter-1-1> > = std::tuple<std::_Placeholder<1>, std::_Placeholder<2>, std::unique_ptr<char [], std::default_delete<char []> > >]' is implicitly deleted because the default definition would be ill-formed:
/usr/include/c++/4.7/tuple:393:17: error: use of deleted function 'constexpr std::_Tuple_impl<_Idx, _Head, _Tail ...>::_Tuple_impl(const std::_Tuple_impl<_Idx, _Head, _Tail ...>&) [with long unsigned int _Idx = 0ul; _Head = std::_Placeholder<1>; _Tail = {std::_Placeholder<2>, std::unique_ptr<char [], std::default_delete<char []> >}; std::_Tuple_impl<_Idx, _Head, _Tail ...> = std::_Tuple_impl<0ul, std::_Placeholder<1>, std::_Placeholder<2>, std::unique_ptr<char [], std::default_delete<char []> > >]'
/usr/include/c++/4.7/tuple:250:17: note: 'constexpr std::_Tuple_impl<_Idx, _Head, _Tail ...>::_Tuple_impl(const std::_Tuple_impl<_Idx, _Head, _Tail ...>&) [with long unsigned int _Idx = 0ul; _Head = std::_Placeholder<1>; _Tail = {std::_Placeholder<2>, std::unique_ptr<char [], std::default_delete<char []> >}; std::_Tuple_impl<_Idx, _Head, _Tail ...> = std::_Tuple_impl<0ul, std::_Placeholder<1>, std::_Placeholder<2>, std::unique_ptr<char [], std::default_delete<char []> > >]' is implicitly deleted because the default definition would be ill-formed:
/usr/include/c++/4.7/tuple:250:17: error: use of deleted function 'constexpr std::_Tuple_impl<_Idx, _Head, _Tail ...>::_Tuple_impl(const std::_Tuple_impl<_Idx, _Head, _Tail ...>&) [with long unsigned int _Idx = 1ul; _Head = std::_Placeholder<2>; _Tail = {std::unique_ptr<char [], std::default_delete<char []> >}; std::_Tuple_impl<_Idx, _Head, _Tail ...> = std::_Tuple_impl<1ul, std::_Placeholder<2>, std::unique_ptr<char [], std::default_delete<char []> > >]'
/usr/include/c++/4.7/tuple:250:17: note: 'constexpr std::_Tuple_impl<_Idx, _Head, _Tail ...>::_Tuple_impl(const std::_Tuple_impl<_Idx, _Head, _Tail ...>&) [with long unsigned int _Idx = 1ul; _Head = std::_Placeholder<2>; _Tail = {std::unique_ptr<char [], std::default_delete<char []> >}; std::_Tuple_impl<_Idx, _Head, _Tail ...> = std::_Tuple_impl<1ul, std::_Placeholder<2>, std::unique_ptr<char [], std::default_delete<char []> > >]' is implicitly deleted because the default definition would be ill-formed:
/usr/include/c++/4.7/tuple:250:17: error: use of deleted function 'constexpr std::_Tuple_impl<_Idx, _Head, _Tail ...>::_Tuple_impl(const std::_Tuple_impl<_Idx, _Head, _Tail ...>&) [with long unsigned int _Idx = 2ul; _Head = std::unique_ptr<char []>; _Tail = {}; std::_Tuple_impl<_Idx, _Head, _Tail ...> = std::_Tuple_impl<2ul, std::unique_ptr<char [], std::default_delete<char []> > >]'
/usr/include/c++/4.7/tuple:250:17: note: 'constexpr std::_Tuple_impl<_Idx, _Head, _Tail ...>::_Tuple_impl(const std::_Tuple_impl<_Idx, _Head, _Tail ...>&) [with long unsigned int _Idx = 2ul; _Head = std::unique_ptr<char []>; _Tail = {}; std::_Tuple_impl<_Idx, _Head, _Tail ...> = std::_Tuple_impl<2ul, std::unique_ptr<char [], std::default_delete<char []> > >]' is implicitly deleted because the default definition would be ill-formed:
/usr/include/c++/4.7/tuple:250:17: error: use of deleted function 'std::_Head_base<2ul, std::unique_ptr<char []>, false>::_Head_base(const std::_Head_base<2ul, std::unique_ptr<char []>, false>&)'
/usr/include/c++/4.7/tuple:122:12: note: 'std::_Head_base<2ul, std::unique_ptr<char []>, false>::_Head_base(const std::_Head_base<2ul, std::unique_ptr<char []>, false>&)' is implicitly deleted because the default definition would be ill-formed:
/usr/include/c++/4.7/tuple:122:12: error: use of deleted function 'std::unique_ptr<_Tp [], _Dp>::unique_ptr(const std::unique_ptr<_Tp [], _Dp>&) [with _Tp = char; _Dp = std::default_delete<char []>; std::unique_ptr<_Tp [], _Dp> = std::unique_ptr<char []>]'
In file included from /usr/include/c++/4.7/memory:86:0,
                 from /usr/include/boost/asio/detail/shared_ptr.hpp:21,
                 from /usr/include/boost/asio/detail/socket_ops.hpp:21,
                 from /usr/include/boost/asio/detail/socket_holder.hpp:20,
                 from /usr/include/boost/asio/detail/reactive_socket_accept_op.hpp:24,
                 from /usr/include/boost/asio/detail/reactive_socket_service.hpp:30,
                 from /usr/include/boost/asio/datagram_socket_service.hpp:26,
                 from /usr/include/boost/asio/basic_datagram_socket.hpp:21,
                 from /usr/include/boost/asio.hpp:20,
                 from server/network/./network-client.hpp:4,
                 from server/network/network-client.cpp:1:
/usr/include/c++/4.7/bits/unique_ptr.h:414:7: error: declared here
In file included from /usr/include/boost/asio/impl/io_service.hpp:18:0,
                 from /usr/include/boost/asio/io_service.hpp:767,
                 from /usr/include/boost/asio/basic_io_object.hpp:19,
                 from /usr/include/boost/asio/basic_socket.hpp:19,
                 from /usr/include/boost/asio/basic_datagram_socket.hpp:20,
                 from /usr/include/boost/asio.hpp:20,
                 from server/network/./network-client.hpp:4,
                 from server/network/network-client.cpp:1:
/usr/include/boost/asio/detail/handler_type_requirements.hpp:83:8: error:   initializing argument 1 of 'char (& boost::asio::detail::two_arg_handler_test(Handler, ...))[2] [with Handler = std::_Bind<oroshi::network::NetworkClient::start()::<lambda(const boost::system::error_code&, std::size_t)>::<lambda(const boost::system::error_code&, std::size_t, std::unique_ptr<char []>&)>(std::_Placeholder<1>, std::_Placeholder<2>, std::unique_ptr<char []>)>]'
In file included from /usr/include/boost/asio.hpp:30:0,
                 from server/network/./network-client.hpp:4,
                 from server/network/network-client.cpp:1:
/usr/include/boost/asio/basic_stream_socket.hpp:515:5: error: static assertion failed: ReadHandler type requirements not met
/usr/include/boost/asio/basic_stream_socket.hpp:515:57: error: use of deleted function 'std::_Bind<_Functor(_Bound_args ...)>::_Bind(const std::_Bind<_Functor(_Bound_args ...)>&) [with _Functor = oroshi::network::NetworkClient::start()::<lambda(const boost::system::error_code&, std::size_t)>::<lambda(const boost::system::error_code&, std::size_t, std::unique_ptr<char []>&)>; _Bound_args = {std::_Placeholder<1>, std::_Placeholder<2>, std::unique_ptr<char [], std::default_delete<char []> >}; std::_Bind<_Functor(_Bound_args ...)> = std::_Bind<oroshi::network::NetworkClient::start()::<lambda(const boost::system::error_code&, std::size_t)>::<lambda(const boost::system::error_code&, std::size_t, std::unique_ptr<char []>&)>(std::_Placeholder<1>, std::_Placeholder<2>, std::unique_ptr<char []>)>]'
In file included from /usr/include/boost/asio/impl/io_service.hpp:18:0,
                 from /usr/include/boost/asio/io_service.hpp:767,
                 from /usr/include/boost/asio/basic_io_object.hpp:19,
                 from /usr/include/boost/asio/basic_socket.hpp:19,
                 from /usr/include/boost/asio/basic_datagram_socket.hpp:20,
                 from /usr/include/boost/asio.hpp:20,
                 from server/network/./network-client.hpp:4,
                 from server/network/network-client.cpp:1:
/usr/include/boost/asio/detail/handler_type_requirements.hpp:95:26: error:   initializing argument 1 of 'T& boost::asio::detail::lvref(T) [with T = std::_Bind<oroshi::network::NetworkClient::start()::<lambda(const boost::system::error_code&, std::size_t)>::<lambda(const boost::system::error_code&, std::size_t, std::unique_ptr<char []>&)>(std::_Placeholder<1>, std::_Placeholder<2>, std::unique_ptr<char []>)>]'
In file included from /usr/include/boost/asio.hpp:30:0,
                 from server/network/./network-client.hpp:4,
                 from server/network/network-client.cpp:1:
/usr/include/boost/asio/basic_stream_socket.hpp:515:57: error: use of deleted function 'std::_Bind<_Functor(_Bound_args ...)>::_Bind(const std::_Bind<_Functor(_Bound_args ...)>&) [with _Functor = oroshi::network::NetworkClient::start()::<lambda(const boost::system::error_code&, std::size_t)>::<lambda(const boost::system::error_code&, std::size_t, std::unique_ptr<char []>&)>; _Bound_args = {std::_Placeholder<1>, std::_Placeholder<2>, std::unique_ptr<char [], std::default_delete<char []> >}; std::_Bind<_Functor(_Bound_args ...)> = std::_Bind<oroshi::network::NetworkClient::start()::<lambda(const boost::system::error_code&, std::size_t)>::<lambda(const boost::system::error_code&, std::size_t, std::unique_ptr<char []>&)>(std::_Placeholder<1>, std::_Placeholder<2>, std::unique_ptr<char []>)>]'
In file included from /usr/include/boost/asio/impl/io_service.hpp:18:0,
                 from /usr/include/boost/asio/io_service.hpp:767,
                 from /usr/include/boost/asio/basic_io_object.hpp:19,
                 from /usr/include/boost/asio/basic_socket.hpp:19,
                 from /usr/include/boost/asio/basic_datagram_socket.hpp:20,
                 from /usr/include/boost/asio.hpp:20,
                 from server/network/./network-client.hpp:4,
                 from server/network/network-client.cpp:1:
/usr/include/boost/asio/detail/handler_type_requirements.hpp:96:32: error:   initializing argument 1 of 'const T& boost::asio::detail::clvref(T) [with T = std::_Bind<oroshi::network::NetworkClient::start()::<lambda(const boost::system::error_code&, std::size_t)>::<lambda(const boost::system::error_code&, std::size_t, std::unique_ptr<char []>&)>(std::_Placeholder<1>, std::_Placeholder<2>, std::unique_ptr<char []>)>]'
In file included from /usr/include/boost/asio.hpp:30:0,
                 from server/network/./network-client.hpp:4,
                 from server/network/network-client.cpp:1:
/usr/include/boost/asio/basic_stream_socket.hpp:515:57: error: use of deleted function 'std::_Bind<_Functor(_Bound_args ...)>::_Bind(const std::_Bind<_Functor(_Bound_args ...)>&) [with _Functor = oroshi::network::NetworkClient::start()::<lambda(const boost::system::error_code&, std::size_t)>::<lambda(const boost::system::error_code&, std::size_t, std::unique_ptr<char []>&)>; _Bound_args = {std::_Placeholder<1>, std::_Placeholder<2>, std::unique_ptr<char [], std::default_delete<char []> >}; std::_Bind<_Functor(_Bound_args ...)> = std::_Bind<oroshi::network::NetworkClient::start()::<lambda(const boost::system::error_code&, std::size_t)>::<lambda(const boost::system::error_code&, std::size_t, std::unique_ptr<char []>&)>(std::_Placeholder<1>, std::_Placeholder<2>, std::unique_ptr<char []>)>]'
In file included from /usr/include/boost/asio/impl/io_service.hpp:18:0,
                 from /usr/include/boost/asio/io_service.hpp:767,
                 from /usr/include/boost/asio/basic_io_object.hpp:19,
                 from /usr/include/boost/asio/basic_socket.hpp:19,
                 from /usr/include/boost/asio/basic_datagram_socket.hpp:20,
                 from /usr/include/boost/asio.hpp:20,
                 from server/network/./network-client.hpp:4,
                 from server/network/network-client.cpp:1:
/usr/include/boost/asio/detail/handler_type_requirements.hpp:97:28: error:   initializing argument 1 of 'char boost::asio::detail::argbyv(T) [with T = std::_Bind<oroshi::network::NetworkClient::start()::<lambda(const boost::system::error_code&, std::size_t)>::<lambda(const boost::system::error_code&, std::size_t, std::unique_ptr<char []>&)>(std::_Placeholder<1>, std::_Placeholder<2>, std::unique_ptr<char []>)>]'
In file included from /usr/include/c++/4.7/functional:56:0,
                 from /usr/include/boost/system/error_code.hpp:23,
                 from /usr/include/boost/asio/io_service.hpp:25,
                 from /usr/include/boost/asio/basic_io_object.hpp:19,
                 from /usr/include/boost/asio/basic_socket.hpp:19,
                 from /usr/include/boost/asio/basic_datagram_socket.hpp:20,
                 from /usr/include/boost/asio.hpp:20,
                 from server/network/./network-client.hpp:4,
                 from server/network/network-client.cpp:1:
/usr/include/c++/4.7/tuple: In instantiation of 'constexpr std::_Head_base<_Idx, _Head, false>::_Head_base(const _Head&) [with long unsigned int _Idx = 2ul; _Head = std::unique_ptr<char []>]':
/usr/include/c++/4.7/tuple:241:44:   recursively required from 'constexpr std::_Tuple_impl<_Idx, _Head, _Tail ...>::_Tuple_impl(const _Head&, const _Tail& ...) [with long unsigned int _Idx = 1ul; _Head = std::_Placeholder<2>; _Tail = {std::unique_ptr<char [], std::default_delete<char []> >}]'
/usr/include/c++/4.7/tuple:241:44:   required from 'constexpr std::_Tuple_impl<_Idx, _Head, _Tail ...>::_Tuple_impl(const _Head&, const _Tail& ...) [with long unsigned int _Idx = 0ul; _Head = std::_Placeholder<1>; _Tail = {std::_Placeholder<2>, std::unique_ptr<char [], std::default_delete<char []> >}]'
/usr/include/c++/4.7/tuple:384:33:   required from 'constexpr std::tuple< <template-parameter-1-1> >::tuple(const _Elements& ...) [with _Elements = {std::_Placeholder<1>, std::_Placeholder<2>, std::unique_ptr<char [], std::default_delete<char []> >}]'
/usr/include/c++/4.7/functional:1196:70:   required from 'std::_Bind<_Functor(_Bound_args ...)>::_Bind(_Functor&&, _Args&& ...) [with _Args = {const std::_Placeholder<1>&, const std::_Placeholder<2>&, std::unique_ptr<char [], std::default_delete<char []> >&}; _Functor = oroshi::network::NetworkClient::start()::<lambda(const boost::system::error_code&, std::size_t)>::<lambda(const boost::system::error_code&, std::size_t, std::unique_ptr<char []>&)>; _Bound_args = {std::_Placeholder<1>, std::_Placeholder<2>, std::unique_ptr<char [], std::default_delete<char []> >}]'
/usr/include/c++/4.7/functional:1527:42:   required from 'typename std::_Bind_helper<std::__is_socketlike<_Func>::value, _Func, _BoundArgs ...>::type std::bind(_Func&&, _BoundArgs&& ...) [with _Func = oroshi::network::NetworkClient::start()::<lambda(const boost::system::error_code&, std::size_t)>::<lambda(const boost::system::error_code&, std::size_t, std::unique_ptr<char []>&)>; _BoundArgs = {const std::_Placeholder<1>&, const std::_Placeholder<2>&, std::unique_ptr<char [], std::default_delete<char []> >&}; typename std::_Bind_helper<std::__is_socketlike<_Func>::value, _Func, _BoundArgs ...>::type = std::_Bind<oroshi::network::NetworkClient::start()::<lambda(const boost::system::error_code&, std::size_t)>::<lambda(const boost::system::error_code&, std::size_t, std::unique_ptr<char []>&)>(std::_Placeholder<1>, std::_Placeholder<2>, std::unique_ptr<char []>)>]'
server/network/network-client.cpp:56:69:   required from here
/usr/include/c++/4.7/tuple:128:25: error: use of deleted function 'std::unique_ptr<_Tp [], _Dp>::unique_ptr(const std::unique_ptr<_Tp [], _Dp>&) [with _Tp = char; _Dp = std::default_delete<char []>; std::unique_ptr<_Tp [], _Dp> = std::unique_ptr<char []>]'
In file included from /usr/include/c++/4.7/memory:86:0,
                 from /usr/include/boost/asio/detail/shared_ptr.hpp:21,
                 from /usr/include/boost/asio/detail/socket_ops.hpp:21,
                 from /usr/include/boost/asio/detail/socket_holder.hpp:20,
                 from /usr/include/boost/asio/detail/reactive_socket_accept_op.hpp:24,
                 from /usr/include/boost/asio/detail/reactive_socket_service.hpp:30,
                 from /usr/include/boost/asio/datagram_socket_service.hpp:26,
                 from /usr/include/boost/asio/basic_datagram_socket.hpp:21,
                 from /usr/include/boost/asio.hpp:20,
                 from server/network/./network-client.hpp:4,
                 from server/network/network-client.cpp:1:
/usr/include/c++/4.7/bits/unique_ptr.h:414:7: error: declared here
Jiwan
  • 731
  • 4
  • 11
  • 3
    Please trim down your code to a shorter example that reproduces your problem, it will be much easier to help you and more useful for other people in the future. From your description I doubt `boost.asio` has anything to do with your issue. – syam Jun 06 '13 at 14:47
  • @syam I added a trimmed and cleaned part. – Jiwan Jun 06 '13 at 14:57
  • 1
    @Jiwan I believe syam meant only post a trimmed, self-contained example of code that exhibits the problem. If the problem is not related to Asio, try to avoid posting the Asio-related code, since it's pretty hard to read. – SirDarius Jun 06 '13 at 15:09
  • @SirDarius: right, I meant an example like the one in the duplicate question you linked. But since it is indeed a duplicate the matter is settled. – syam Jun 06 '13 at 15:17
  • @SirDarius If i'm right the "semi-convoluted" solution using std::bind by marton78, transfer a unique_ptr to a naked pointer and isn't a transfer from an unique_ptr to another unique_ptr. No ? – Jiwan Jun 06 '13 at 15:27
  • @Jiwan: yes, so it doesn't solve your issue as it still introduces lifetime problems. The real answer is the accepted one (Nicol Bolas): *you can't **move** an object instance to a lambda, it has to be copyable*. – syam Jun 06 '13 at 15:30
  • As for your particular problem, is it acceptable to use `shared_ptr` instead of `unique_ptr`? It would solve the "copyable" issue. That's the only way out I can see. – syam Jun 06 '13 at 15:31
  • @syam Sorry i just read Nicol Bolas part that where he said "To do what you want will require either using std::bind (which would be semi-convoluted, requiring a short sequence of binds) or just returning a regular old object." and thought it was possible like so. For sure a shared_ptr will solve my problem as it provide a copy constructor, but i wanted to solve this problem instead of avoid it. – Jiwan Jun 06 '13 at 15:38
  • @Jiwan well, by definition, a unique_ptr is unique, if you pass it to a lambda, then it would be _shared_ with this lambda, wouldn't it ? So inevitably, a shared_ptr solves the problem. – SirDarius Jun 06 '13 at 15:40
  • @Jiwan: to understand why lambdas can't capture non-copyable, movable-only objects, see my explanation about [how lambdas are implemented under the hood](http://stackoverflow.com/questions/16921247/how-are-c11-lambdas-represented-and-passed/16922118#16922118) (shameless plug :p). 5.1.2-19 mandates that a lambda closure-type has a copy constructor so it is obviously incompatible with moveable-only captured objects. – syam Jun 06 '13 at 15:48
  • You can get this sort of thing working by changing the lambda parameter type to an lvalue reference. http://stackoverflow.com/a/9957110/459640 – aschepler Jun 06 '13 at 15:50
  • 1
    @aschepler: Won't help in this case: the `unique_ptr` will already be destroyed by the time the lambda gets called. – syam Jun 06 '13 at 15:52
  • http://ideone.com/FWnrCh – aschepler Jun 06 '13 at 15:52
  • @syam: Oh, good point. Maybe a `shared_ptr` would be a better idea here. – aschepler Jun 06 '13 at 15:53

0 Answers0