Say I am writing a enqueue()
function that takes in a unique_ptr
, but I only want to claim its ownership when enqueue returns success. If the queue is full I want to leave the unique_ptr
intact (user can retry with the same item later)
bool enqueue(std::unique_ptr&& item){
if(!vector.full()){
vector.emplace(std::move(item));
return true;
}
return false;
}
// usage
auto item_ptr = make_unique<>();
while(!enqueue(std::move(item_ptr))){
// item_ptr is not moved
}
I can also define the function to take a lvalue reference instead
bool enqueue(std::unique_ptr& item)
while(!enqueue(item_ptr)){
// item_ptr is not moved
}
I am not sure which one to pick, they all seemed a little anti-patterned since usually std::move
indicates the deletion of a unique_ptr (most of the time, I work with function that takes unique_ptr
by value), maybe there's a better solution?
You could return a unique_ptr from your function. If it failed return the original. If it succeeded return an empty unique_ptr.
Then you could call it like:
#include <iostream>
#include <memory>
#include <vector>
int counter = 10;
template <typename T> std::unique_ptr<T> enqueue(std::unique_ptr<T> p) {
if (--counter == 0)
return std::unique_ptr<T>();
return p;
}
int main() {
auto item_ptr = std::make_unique<int>(8);
while (item_ptr = enqueue(std::move(item_ptr))) {
std::cout << "looping\n";
}
std::cout << "moved\n";
return 0;
}
Actually, I'd better go try this out. Yeah my first idea had a bug. Ripping out that !
from the while loop. Always test. :-)