I can compile the following code:
void threadFunc(Vec3f *&buffer) {}
...
std::unique_ptr<Vec3f []> buffer(new Vec3f[100]);
Vec3f *b = buffer.get();
std::thread(threadFunc, std::ref(b)).join();
But I can't compile:
std::thread(threadFunc, std::ref(buffer.get())).join();
I get the following error at compile time:
error: use of deleted function ‘void std::ref(const _Tp&&) [with _Tp = Vec3<float>*]’
EDIT: the thread is joined before unique_ptr goes out of scope
What's different between the 2 versions? Can I make the second solution work?
Additionally, it seems better to pass by reference a pointer to the managed object than the unique_ptr by reference itself (the threadFunc only has to modify the content of buffer
). Something like:
void threadFunc(std::unique_ptr<Vec3f []> &ptr) {}
std::thread(threadFunc, std::ref(buffer)).join();
Would this be bad practice? Or is this acceptable as well? It seems to me that if I want to change the content of buffer, this is what I should pass to the thread function, not the unique_ptr itself? Any recommendation would be appreciated.
EDIT 2:
So According to one of the answers below, the second option is not possible because std::ref(buffer.get())
uses some temp object. Though the first version despite what's said should work (I can't see why this would be invalid):
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));
same as:
std::thread(threadFunc, std::ref(tmp));
As for the solution provided:
void threadFunc(Vec3f *buffer) { buffer[0] = 0; // invalid }
Vec3f *buffer = new Vec3f[100];
std::thread(threadFunc, buffer);
It seems invalid to me as buffer
is passed by value and not by reference, however I need to write to buffer. So it needs to be passed by ref.
If someone could clarify it would be great.