Мне нужно сделать что-то подобное более часто:
AsyncOperation * pAsyncOperation = new AsyncOperation();
auto bindOperation = std::bind(&AsyncOperation::operator(), std::ref(*pAsyncOperation));
std::thread thread(bindOperation );
thread.join();
с AsyncOperation
быть любым пользовательским классом, реализующим operator()
(также известный как функтор или функциональный объект).
Можно ли указать std::bind
использовать std::shared_ptr
вместо std::ref
?
Это предотвратило бы утечки памяти, без необходимости сохранять ссылку на pAsyncOperation
и удалил бы AsyncOperation
автоматически в конце потока, это конец этой асинхронной задачи.
РЕДАКТИРОВАТЬ: У меня не всегда есть доступ к std :: thread, библиотека потоков может быть boost :: thread или даже любые другие зависимые от платформы потоки. И, как следствие, нет доступа к std :: async.
Моя главная проблема заключается в том, чтобы иметь представление о владении в std :: bind.
Это работает:
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();
}
Увидеть: http://liveworkspace.org/code/4bc81bb6c31ba7b2bdeb79ea0e02bb89
Тебе нужно AsyncOperation
выделяться динамически? Если нет, я бы сделал это:
auto f = std::async([]{ AsyncOperation()(); });
f.wait();
иначе:
std::unique_ptr<AsyncOperation> op(new AsyncOperation);
auto f = std::async([&]{ (*op)(); });
f.wait();
Вы можете, конечно, использовать std::thread
, но это может обеспечить больше проблем (то есть обработку исключений в другом потоке). std::bind
также есть свои проблемы, и вам, вероятно, лучше будет получить лямбду.
Если вам действительно нужно передать право собственности другому потоку, вы также можете сделать это:
std::unique_ptr<AsyncOperation> op(new AsyncOperation);
auto f = std::async([&](std::unique_ptr<AsyncOperation> op){ (*op)(); }, std::move(op));
f.wait();
поскольку лямбды еще не поддерживают захваты типа перемещения.
Надеюсь, это поможет.