Creating an object and giving ownership to a container using a unique_ptr is no problem. How would one remove an element by raw pointer?
std::set<std::unique_ptr<MyClass>> mySet;
MyClass *myClass = new MyClass();
mySet.insert(std::unique_ptr<MyClass>(myClass));
// remove myClass from mySet?
An explicit delete for a unique_ptr would be reset() . But do remember that unique_ptr are there so that you don't have to manage directly the memory they hold. That is, you should know that a unique_ptr will safely delete its underlying raw pointer once it goes out of scope.
std::unique_ptr is a smart pointer that owns and manages another object through a pointer and disposes of that object when the unique_ptr goes out of scope.
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.
You will need to find the iterator corresponding to the myClass
element and then pass that iterator to mySet.erase()
. The iterator may be found using the std::find_if
algorithm with a custom Predicate
functor that understands how to dereference unique_ptr
and compare it to the raw pointer myClass
.
You can not use the overloaded size_t set::erase ( const key_type& x );
since the raw pointer (even if wrapped in a temporary unique_ptr
) will not be found in mySet
.
Not as pretty as I would've liked. But the following does the job:
#include <memory>
#include <set>
#include <iostream>
struct do_nothing
{
void operator()(const void*) const {}
};
struct MyClass
{
MyClass() {std::cout << "MyClass()\n";}
MyClass(const MyClass&) {std::cout << "MyClass(const MyClass&)\n";}
~MyClass() {std::cout << "~MyClass()\n";}
};
int main()
{
std::set<std::unique_ptr<MyClass>> mySet;
MyClass *myClass = new MyClass();
mySet.insert(std::unique_ptr<MyClass>(myClass));
// remove myClass from mySet?
std::set<std::unique_ptr<MyClass>>::iterator i =
lower_bound(mySet.begin(), mySet.end(),
std::unique_ptr<MyClass, do_nothing>(myClass));
if (i != mySet.end() && *i == std::unique_ptr<MyClass, do_nothing>(myClass))
mySet.erase(i);
}
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