I can't seem to figure this out and have tried the suggestions in:
Move `unique_ptr`s between sets
how to move an std::unique_ptr<> from one STL container to another?
I have two sets containing unique pointers:
std::set<std::unique_ptr<some_type>> s1, s2;
The pointers are of course unique but the values of some_type may or may not be, so after joining the s2 into s1, s1's size may be the same or as large as |s1 + s2|.
It seems like I should be able to do this:
move(s2.begin(), s2.end(), inserter(s1, s1.end()));
But this fails with clang++ 3.8 / g++ 5.4.
What am missing here?
A unique_ptr can only be moved. This means that the ownership of the memory resource is transferred to another unique_ptr and the original unique_ptr no longer owns it. We recommend that you restrict an object to one owner, because multiple ownership adds complexity to the program logic.
In C++11 we can transfer the ownership of an object to another unique_ptr using std::move() . After the ownership transfer, the smart pointer that ceded the ownership becomes null and get() returns nullptr.
It can be assigned: class owner { std::unique_ptr<someObject> owned; public: owner() { owned=std::unique_ptr<someObject>(new someObject()); } };
unique_ptr::getReturns a pointer to the managed object or nullptr if no object is owned.
It doesn't work because a std::set
only gives const
access to its elements. There is no way to move something out of a std::set
. See Is it possible to move an item out of a std::set?
There's no good way to do this in C++14, but in C++17 there is a merge
method provided for this purpose, which simply rearranges the internal pointers of the data structures without copying or moving any elements:
s1.merge(s2);
A somewhat reasonable workaround in C++14 is to change std::set<std::unique_ptr<T>>
to std::map<T*, std::unique_ptr<T>>
. Then you can do:
while (!s1.empty()) {
s2[s1.begin()->first] = std::move(s1.begin()->second);
s1.erase(s1.begin());
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With