c++ - 通过引用线程函数传递 unique_ptr 的托管对象

标签 c++ multithreading unique-ptr

我可以编译以下代码:

void threadFunc(Vec3f *&buffer) {}
...
std::unique_ptr<Vec3f []> buffer(new Vec3f[100]);
Vec3f *b = buffer.get();
std::thread(threadFunc, std::ref(b)).join();

但我无法编译:

std::thread(threadFunc, std::ref(buffer.get())).join();

我在编译时收到以下错误:

error: use of deleted function ‘void std::ref(const _Tp&&) [with _Tp = Vec3<float>*]’

编辑:在 unique_ptr 超出范围之前加入线程

这两个版本有什么不同?我可以使第二个解决方案起作用吗?

此外,通过引用传递指向托管对象的指针似乎比通过引用本身传递 unique_ptr 更好(threadFunc 只需修改 buffer 的内容)。像这样的东西:

void threadFunc(std::unique_ptr<Vec3f []> &ptr) {}
std::thread(threadFunc, std::ref(buffer)).join();

这是不好的做法吗?或者说这也是可以接受的?在我看来,如果我想更改缓冲区的内容,这就是我应该传递给线程函数的内容,而不是 unique_ptr 本身?如有任何建议,我们将不胜感激。

编辑2:

因此,根据下面的答案之一,第二个选项是不可能的,因为 std::ref(buffer.get()) 使用一些临时对象。尽管第一个版本尽管所说应该有效(我不明白为什么这会无效):

Vec3f *tmp = new Vec3f[100];
std::unique_ptr<Vec3f []> buffer = std::unique_ptr<Vec3f []>(tmp);
Vec3f *b = buffet.get(); // address of b == address of tmp
std::thread(threadFunc, std::ref(b));

与:

相同
std::thread(threadFunc, std::ref(tmp));

至于提供的解决方案:

void threadFunc(Vec3f *buffer) { buffer[0] = 0; // invalid }
Vec3f *buffer = new Vec3f[100];
std::thread(threadFunc, buffer);

这对我来说似乎无效,因为 buffer 是按值传递而不是按引用传递,但是我需要写入缓冲区。所以需要通过ref来传递。

如果有人能澄清那就太好了。

最佳答案

它不起作用的原因是因为您正在尝试获取对临时对象的引用。而你不能这样做,因为它里面的reference_wrapper只有指针,并且它拒绝保存指向临时对象的指针。编译的版本可能实际上是错误的,因为您传递了一个指向托管对象的指针,该对象可能在其他线程中使用时被删除(除非该线程在 unique_ptr 超出范围之前加入)

顺便说一句,unique_ptr 的设计正是为了让您摆脱这些困境。只需按值传递 unique_ptr,然后让另一个线程管理它的生命周期。

编辑:根据我们的讨论,线程似乎是在 unique_ptr 超出范围之前加入的。如果我的理解是正确的,那么您根本不需要向线程函数提供 unique_ptr 。以下是一个完美的(伪)代码:

typedef <your type> type_t;
void handle_func(type_t* ptr);
typedef std::unique_ptr<type_t> ptr_t;

ptr_t ptr(new type_t);
std::thread handler(handle_func, ptr.get());
handler.join();

顺便说一句,从上面的代码片段来看,甚至不清楚为什么需要 unique_ptr - 而不是简单地使用局部变量并向其传递地址或 ref() 。我想,这是有我不知道的原因的:)

关于c++ - 通过引用线程函数传递 unique_ptr 的托管对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32722475/

相关文章:

linux - 为什么我的两个线程不交错运行?

c++ - eclipse 中的 unique_ptr 自动完成

c++ - move std::unique_ptr的构造函数/分配:内存重新分配?

c++ - 公共(public)继承的静态断言

c++ - 编译外部 C++ 库以用于 iOS 项目

c++ - QImage垂直翻转

c - 我需要了解编译器如何解释 &tcb -> context

Java:让其他线程知道 GUI 是否可以使用

c++ - 无法理解工作代码和损坏代码之间的区别

c++ - unique_ptr 所有权语义