Is there a transparent way of using std::unique_ptr
in containers?
#include <iostream>
#include <memory>
#include <map>
struct method {
virtual ~method() { std::cout << "f\n"; };
};
typedef std::unique_ptr<method> MPTR;
std::map<int, MPTR> tbl;
void insert(int id, method *m) {
tbl.insert({id,std::unique_ptr<method>(m)});
};
void set(int id, method *m) {
tbl[id] = std::unique_ptr<method>(m);
};
int main(int argc, char **argv) {
insert(1,new method());
set(1,new method());
return 0;
}
I'd like to use tbl.insert({id,m});
and tbl[id] = m;
etc. instead of having to wrap/unwrap for each access.
- Are there implementations of std containers for unique_ptr? In particular
std::map
. - How would a transparent interface be implemented?
When you pass a raw pointer into a function, it is generally unknown who is expected to keep ownership of the pointed-to object when the function exits - the caller or the callee. There is nothing in the language to specify or enforce that.
So, it is generally good practice to pass in a raw pointer only when the callee reads or modifies the object but the caller is expected to maintain ownership.
In your example, that is not the case. You want your functions to take ownership of the allocated
method
objects. So, you should change your functions to pass instd::unique_ptr<method>
objects by value, instead of passing rawmethod*
pointers. That makes it very explicit that ownership is expected to pass from the caller to the callee, eg:Live demo
Why? This hides information from the reader. It is important to know whether something is dynamically allocated or not.
Not in the Standard Library.
Store a normal container inside your wrapper, provide forwarding functions that create
unique_ptr
where required. Iterators could unwrap automatically. E.g.Generally, we don't want to implicitly create
std::unique_ptr
because that can be dangerous.In this sample, I'd recommend starting out with a
unique_ptr
rather than a barenew
. This makes sure the entire lifetime is tracked.within
insert
you can also usestd::move
to transfer ownership to the collection.