WBuck
WBuck

Reputation: 5503

unique_ptr, you're referencing a deleted function

I'm attempting to move a unique_ptr to the WriteAsync method. This works as expected. The issue I'm having is now moving ownership of the unique pointer into the strand.post lambda, and then, moving it again, into QueueMessage. QueueMessage takes a std::unique_ptr<std::vector<char>>.

The easy way for me in this case would be to just use a shared_ptr. I'm wondering if there is a way to make this work without the use of a shared_ptr.

// Caller
static void DoWork( char const* p, int len  )
{
     client.WriteAsync( std::make_unique<std::vector<char>>( p, p + len ) );
}

// Callee
void TcpClient::WriteAsync( std::unique_ptr<std::vector<char>> buffer )
{
    _strand.post( [ this, buffer = std::move( buffer ) ]( ) 
    { 
        // Error on this line.
        QueueMessage( std::move( buffer ) ); 
    } );
}


void TcpClient::QueueMessage( std::unique_ptr<std::vector<char>> buffer )
{
     // Do stuff
}

The error I'm seeing is:

you're referencing a deleted function

Upvotes: 1

Views: 805

Answers (1)

Praetorian
Praetorian

Reputation: 109089

A lambda's function call operator is a const member function. So std::move(buffer) will return std::unique_ptr<std::vector<char>>> const&&, which matches the deleted unique_ptr copy constructor instead of its move constructor, hence the error.

To fix the error, make your lambda mutable, this will make operator()() non-const, allowing you to move construct buffer

[ buffer = std::move( buffer ) ] ( ) mutable 
//                                   ^^^^^^^
{
   QueueMessage( std::move( buffer ) );
}

Upvotes: 8

Related Questions