chriskohlhoff / asio

Asio C++ Library
http://think-async.com/Asio
4.98k stars 1.22k forks source link

io_service::strand does not support perfect forwarding (move) #1369

Open ujos opened 1 year ago

ujos commented 1 year ago

It seems strand is unable to move objects. Instead it copies it:

boost v1.83.0

#include <boost/asio.hpp>
#include <functional>

using namespace std::placeholders;

struct X {
   X() = default;
   X(X&&) = default;  // Enable move ctor and disable copy ctor
   X& operator=(X&&) = default;  // Enable move assignment and disable copy assignment
};

void foo(int&&) {}
void bar(X&&) {}

void test1()
{
   auto svc = boost::asio::io_service{};
   auto strnd = boost::asio::io_service::strand{svc};
   auto f1 = std::bind(foo, _1);
   f1(1); // ensure I'm able to call it
   auto f2 = strnd.wrap(std::move(f1));
   // boost/asio/detail/bind_handler.hpp:171:49: error: no match for call to '(std::_Bind<void (*(std::_Placeholder<1>))(int&&)>) (const int&)'
   f2(1);
}

void test2()
{
   auto svc = boost::asio::io_service{};
   auto strnd = boost::asio::io_service::strand{svc};
   auto f1 = std::bind(bar, _1);
   f1(X{}); // ensure I'm able to call it
   auto f2 = strnd.wrap(std::move(f1));
   // boost/asio/detail/bind_handler.hpp:145:7: error: use of deleted function 'constexpr X::X(const X&)'
   f2(X{}); 
}