Как совместить использование 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 автоматически в конце потока, это конец этой асинхронной задачи.

РЕДАКТИРОВАТЬ: У меня не всегда есть доступ к std :: thread, библиотека потоков может быть boost :: thread или даже любые другие зависимые от платформы потоки. И, как следствие, нет доступа к std :: async.

Моя главная проблема заключается в том, чтобы иметь представление о владении в std :: bind.

11

Решение

Это работает:

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

12

Другие решения

Тебе нужно 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();

поскольку лямбды еще не поддерживают захваты типа перемещения.

Надеюсь, это поможет.

7

По вопросам рекламы [email protected]