Как объединить использование std:: bind с std:: shared_ptr
Мне нужно сделать что-то подобное более часто:
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
в конце потока, что является завершением этой асинхронной задачи.
EDIT: у меня не всегда есть доступ к std:: thread, потоковая библиотека может быть boost:: thread или даже любыми другими зависимыми от платформы потоками. И, следовательно, не доступ к std:: async.
Моя основная проблема заключается в том, чтобы иметь представление о владении в std:: bind.
Ответы
Ответ 1
Это работает:
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
Ответ 2
Вам нужно 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();
поскольку lambdas еще не поддерживают захват типа перемещения.
Я надеюсь, что это поможет.