
[Peter Dimov]
My initial implementation of boost::make_shared was a self-contained header that didn't require any changes to shared_ptr (it would have worked with std::tr1::shared_ptr as well as it worked with boost::shared_ptr). This can only be done with a free function.
Aha - that's an interesting bit of history!
(However, it can be argued that this support - the ability to ask for a deleter of a specific type to be default-constructed in place by shared_ptr - should be offered to users as well, not just to make_shared.)
I don't look at Boost's implementation, but this makes me curious as to whether you implement the "we know where you live" optimization. On x86, for a 4-byte Foobar, how big is your reference count control block for make_shared<Foobar>()? Mine is 16 bytes. [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. STL