Consider this program:
#include <memory>
struct T {
T() {}
};
void do_something(std::shared_ptr<T> ptr) {
// Do something with ptr; might or might not leave
// other copies of ptr in other variables of the
// program
}
int main() {
std::shared_ptr<T> ptr = std::make_shared();
do_something(ptr);
// ptr might or might not be the only owner
ptr = std::make_shared();
return 0;
}
When make_shared
executes for the second time, ptr
might or might have other sharing owners, depending on what happens at runtime in do_something
. If there are no others, ptr
destructs and deallocates its previously owned object, when more or less at the same time a new object of the same time is allocated and constructed. Is there any way to avoid the allocation and deallocation, and use the same region for constructing the new object? (the target here is to optimize the two calls to the allocator)
Of course I accept that the new T
object will be constructed after the old one will be destructed, while in the code above the opposite happens. So I would like something like ptr.replace<U>(args)
which does the following: it decrements ptr
's reference count; if the count goes to zero, there are no other weak references and U
is the most derived type of the content of ptr
, it destructs the owned object and it constructs a new one with arguments args
in the same memory region, avoiding calls to the memory allocator. Otherwise it behaves like ptr = std::make_shared<U>(args)
.
Is there anyway to perform this optimization with the current standard library?