I need to do something like this more than often:
AsyncOperation * pAsyncOperation = new AsyncOperation();
auto bindOperation = std::bind(&AsyncOperation::operator(), std::ref(*pAsyncOperation));
std::thread thread(bindOperation );
thread.join();
with AsyncOperation
being any custom class implementing operator()
(also known as function object).
Is it possible to indicate to the std::bind
to use a std::shared_ptr
instead of a std::ref
?
This would prevent memory leaks, without my needing to keep a reference on pAsyncOperation
, and would delete the AsyncOperation
automatically at the end of the thread, that is the end of this asynchronous task.
EDIT: I don't always have access to std::thread, the thread library can be boost::thread or even any other platform dependent threads. And by consequence, not access to std::async.
My main issue is to have a notion of ownership in the std::bind.
This works:
struct AsyncOperation {
void operator()()
{
std::cout << "AsyncOperation" << '\n';
}
};
int main() {
std::shared_ptr<AsyncOperation> pAsyncOperation = std::make_shared<AsyncOperation>();
auto bindOperation = std::bind(&AsyncOperation::operator(), pAsyncOperation);
std::thread thread(bindOperation );
thread.join();
}
See: http://liveworkspace.org/code/4bc81bb6c31ba7b2bdeb79ea0e02bb89
Do you need AsyncOperation
to be allocated dynamically? If not, I would do that:
auto f = std::async([]{ AsyncOperation()(); });
f.wait();
otherwise:
std::unique_ptr<AsyncOperation> op(new AsyncOperation);
auto f = std::async([&]{ (*op)(); });
f.wait();
You can of course use std::thread
, but it can provide more problems (i.e. exception handling in other thread). std::bind
has also its own problems and you will probably better end up with a lambda.
If you really need to pass an ownership to other thread you can also do that:
std::unique_ptr<AsyncOperation> op(new AsyncOperation);
auto f = std::async([&](std::unique_ptr<AsyncOperation> op){ (*op)(); }, std::move(op));
f.wait();
as lambdas do not support move type captures yet.
I hope that helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With