
Stephan T. Lavavej wrote:
[Fabio Fracassi]
speaking of which (i.e. deleter and make_shared) is there any way to get the optimized layout and a custom deleter? Because if I understand correctly neither make_shared nor allocate_shared can be used with custom deleters?
Ordinary shared_ptrs have separate objects and reference count control blocks. The object, allocated by the user, needs to be disposed of - that's what a custom deleter is for. Custom allocators are used to allocate and deallocate the control block.
With make_shared<T>(), the object isn't constructed by the user, it's constructed by the shared_ptr, and it lives within the control block. Therefore, there's no need for a custom deleter. allocate_shared<T>()'s custom allocator performs the single dynamic memory allocation and deallocation.
It can still make sense to have a custom deleter, to be used by make_shared in place of the explicit destructor call it issues on the embedded object. I don't have a specific use case in mind now though, maybe Fabio can provide one. Something like make_shared<int> to hold a file descriptor, with close() needing to be called instead of ~int. One can implement something like that from the user side, via the equivalent of make_shared< pair<T,D> >, where the pair has a destructor that calls d_(t_), and then using the aliasing constructor on the result to get a shared_ptr<T>. On this same note, allocate_shared ought to use the construct and destroy members of the allocator, so it also provides a similar (but not quite the same) customization point.