Closed domino-succ closed 7 years ago
The type signature of upsert
is flexible enough to allow you to pass in just the constructor arguments you need, and it will call the shared_ptr constructor with whatever you pass it if the insert occurs. This is essentially the behavior of emplace
in the STL containers.
Unfortunately, shared_ptr
doesn't seem to have a constructor that will allocate a new pointer for you, it can only take ownership of existing pointers or shared_ptrs
. So I'm not sure if there's a super clean solution to avoid constructing a shared_ptr
in the case where the key is already in the table.
One way I can think of is to create a wrapper class around the shared_ptr
, whose default constructor allocates the shared_ptr
with a new instance of class
. So you could have something like
struct shared_ptr_wrapper {
shared_ptr<class> ptr;
shared_ptr_wrapper() : ptr(new class) {}
};
Then you could write your function as
void my_update (int num) {
auto fn = [num](shared_ptr_wrapper& p){ *** };
mp.upsert(key, fn);
}
And if the map needs to insert the key, it'll call the shared_ptr_wrapper
constructor with no arguments and construct the shared_ptr
the way you want.
it will call the shared_ptr constructor with whatever you pass it if the insert occurs
What if I want to new a class with a parameter, say 6. Like new class(6)
. How can I pass 6
to the constructor in upsert
.
If you go with the wrapper class approach I outlined, you can create another constructor in the wrapper class that accepts an integer, and then just call upsert as mp.upsert(key, fn, 6)
. If you want to write one totally generic constructor, you can utilize perfect forwarding and write the shared_ptr_wrapper
constructor as follows:
template <typename... Args>
shared_ptr_wrapper(Args&&... args) : ptr(std::make_shared<class>(std::forward<Args>(args)...))) {}
This constructor will essentially forward any of the arguments you pass in upsert
to the class
constructor.
Got you. I'll try that. Thanks
For example, I have a
cuckoomp<string, shared_ptr<class>> mp
;I have to update like this:
The problem is, every time when
my_update
is invoked, it new a class, even though this class might not be used. How can I avoid this?