[英]Passing the managed object of a unique_ptr by reference to a thread function
我可以編譯以下代碼:
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本身? 任何建議,將不勝感激。
因此,根據以下答案之一,第二個選項是不可能的,因為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()。 我想這是我不知道的原因:)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.