Самый простой способ - использовать функцию-оболочку, которая записывает результат обратно в foo_ptr
:
std::thread foo_thread([&foo_ptr]() {
foo_ptr = update(std::move(foo_ptr));
});
foo_thread.join();
std::cout<< "data: " << *foo_ptr <<std::endl;
Обратите внимание, что между вызовом конструктора std::thread
и завершением join()
вызов, основной поток не должен иметь доступ к foo_ptr
в любом случае. Это будет гонка данных. До конструктора и после join
это нормально, так как оба этих вызова служат точками синхронизации, но любой доступ между ними будет несинхронизирован и будет выполняться с записью в foo_ptr
внутри лямбды.
Если это звучит слишком опасно, рассмотрим подход, в котором поток помещает результат в std::promise
, а основной поток затем получает объект из соответствующего std::future
:
std::promise<IntPtr> p;
std::future<IntPtr> fut = p.get_future();
std::thread foo_thread([ptr = std::move(foo_ptr), p = std::move(p)]() mutable {
p.set_value(update(std::move(ptr)));
});
foo_ptr = std::move(fut.get());