[shared_ptr] Can the custom deleter be a simple function?
The shared_ptr docs suggest that a smart pointer employing a null deleter can be implemented using a functor. Why prefer a functor to a function? Thx, - Rob.
on Sun Nov 06 2011, Robert Jones
The shared_ptr docs suggest that a smart pointer employing a null deleter can be implemented using a functor. Why prefer a functor to a function?
Two reasons I can think of: - Function objects can have a templated operator(), so you don't need to write a new one for each T in shared_ptr<T>. - One less level of function call indirection (very minor win) -- Dave Abrahams BoostPro Computing http://www.boostpro.com
On Sun, Nov 06, 2011 at 12:17:01PM -0900, Dave Abrahams wrote:
on Sun Nov 06 2011, Robert Jones
wrote: The shared_ptr docs suggest that a smart pointer employing a null deleter can be implemented using a functor. Why prefer a functor to a function?
Two reasons I can think of:
- Function objects can have a templated operator(), so you don't need to write a new one for each T in shared_ptr<T>.
- One less level of function call indirection (very minor win)
Let's not forget a very strong reason - functors can contain arbitrary state, as that provided when binding arguments to a callable with Boost.Bind, or any user-defined functor or stateful lambda. A naked free function pointer should really not appear in a modern C++ interface, it's something you expect to see in a C-style API, with some void* blob of "context" passed in if very lucky. -- Lars Viklund | zao@acc.umu.se
On Sun, Nov 6, 2011 at 8:52 PM, Robert Jones
The shared_ptr docs suggest that a smart pointer employing a null deleter can be implemented using a functor. Why prefer a functor to a function?
Thanks Gents - The phrasing of my question was hopelessly lax: I appreciate in the general case why one might choose to use a functor rather than a function as a callable object, what I didn't grasp (and there may be nothing to grasp), was why this (from the shared_ptr docs) struct null_deleter { void operator()(void const *) const { } }; Is implemented as a functor rather than a function. It's already void*, so I think no considerations of static polymorphism or templating, and no state, but maybe there's something else I've not thought of? Thx - Rob.
Robert Jones wrote:
Thanks Gents - The phrasing of my question was hopelessly lax: I appreciate in the general case why one might choose to use a functor rather than a function as a callable object, what I didn't grasp (and there may be nothing to grasp), was why this (from the shared_ptr docs)
struct null_deleter { void operator()(void const *) const { } };
Is implemented as a functor rather than a function.
There's nothing to grasp. The only difference is that sizeof( null_deleter ) is 1, whereas sizeof the function would be 4 or 8, but due to alignment, they both will take up the same space in the actual control block, so it doesn't matter one bit. Using a functor here is purely coding style - the size difference, the fact that operator() would be inlined, the ability to template operator() could all have been relevant in another context.
On Mon, Nov 7, 2011 at 3:15 PM, Peter Dimov
Robert Jones wrote:
Thanks Gents - The phrasing of my question was hopelessly lax: I appreciate in the general case why one might choose to use a functor rather than a function as a callable object, what I didn't grasp (and there may be nothing to grasp), was why this (from the shared_ptr docs)
struct null_deleter { void operator()(void const *) const { } };
Is implemented as a functor rather than a function.
There's nothing to grasp. The only difference is that sizeof( null_deleter ) is 1, whereas sizeof the function would be 4 or 8, but due to alignment, they both will take up the same space in the actual control block, so it doesn't matter one bit. Using a functor here is purely coding style - the size difference, the fact that operator() would be inlined, the ability to template operator() could all have been relevant in another context.
Thank you Peter - your confirmation is appreciated. - Rob.
on Mon Nov 07 2011, "Peter Dimov"
Robert Jones wrote:
Thanks Gents - The phrasing of my question was hopelessly lax: I
appreciate in the general case why one might choose to use a functor rather than a function as a callable object, what I didn't grasp (and there may be nothing to grasp), was why this (from the shared_ptr docs)
struct null_deleter { void operator()(void const *) const { } };
Is implemented as a functor rather than a function.
There's nothing to grasp. The only difference is that sizeof( null_deleter ) is 1,
...or effectively zero if EBO is leveraged. -- Dave Abrahams BoostPro Computing http://www.boostpro.com
participants (4)
-
Dave Abrahams
-
Lars Viklund
-
Peter Dimov
-
Robert Jones