Now you can do something crazy like rewrite the bind so that it can handle movable items, as i did in my post movable-stdbind-with-placeholders. Which is all well and good in theroy BUT there is something to be said about keeping to the standard and well used libs(like boost). Why? Well compiler developers and lib devs like the boost guys are working very hard to improve there stuff. So if you keep to the standard tools and libs you get all the bonuses from their hard work for free when u upgrade. Compiler designers research, profile and add better optimizations and well used libs get more and more eyes on, who in turn find and contribute better code.
And second to all that there is a really trivial and obvious solution to the problem: std::shared_ptr...
So here is how you use std::promise and std::future in lambdas, binds, asio and anything else u cant move into.. I also tossed in an example of how to use non-blocking checks on the futures which is another key tool for using futures in asio code.
#include <iostream> #include <chrono> #include <thread> #include <future> #include <boost/asio.hpp> void asyncRun() { std::cout << "Async..." << std::flush; boost::asio::io_service io_service; std::shared_ptr< std::promise<int> > promise(new std::promise<int>()); std::future<int> future = promise->get_future(); io_service.post( [promise]() { std::chrono::milliseconds dura( 2000 ); std::this_thread::sleep_for( dura ); promise->set_value(9); } ); std::thread t1( [&io_service]{ io_service.run(); }); t1.detach(); std::cout << "Waiting..." << std::flush; future.wait(); std::cout << "Done!\nResults are: " << future.get() << '\n'; } void nonBlockingRun() { std::cout << "Non Blocking..." << std::flush; std::promise<int> promise; std::future<int> future = promise.get_future(); std::thread t1( [](std::promise<int> p) { std::chrono::milliseconds dura( 2000 ); std::this_thread::sleep_for( dura ); p.set_value(9); }, std::move(promise) ); t1.detach(); std::cout << "Waiting...\n" << std::flush; std::future_status status; do { status = future.wait_for(std::chrono::seconds(0)); if (status == std::future_status::deferred) { std::cout << "+"; } else if (status == std::future_status::timeout) { std::cout << "."; } } while (status != std::future_status::ready); std::cout << "Done!\nResults are: " << future.get() << '\n'; } void blockingRun() { std::cout << "Blocking..." << std::flush; std::promise<int> promise; std::future<int> future = promise.get_future(); std::thread t1( [](std::promise<int> p) { std::chrono::milliseconds dura( 2000 ); std::this_thread::sleep_for( dura ); p.set_value(9); }, std::move(promise) ); t1.detach(); std::cout << "Waiting..." << std::flush; future.wait(); std::cout << "Done!\nResults are: " << future.get() << '\n'; } int main() { nonBlockingRun(); blockingRun(); asyncRun(); }
That post is 10 years old but I still want to say you Thank you!
ReplyDelete