casting shared_ptr to function to void

If I have boost::shared_ptr<some_class>, it's possible to cast it to shared_ptr<void>. But it does not appear to be any way to convert pointer to function to pointer to void -- just because there's no implicit conversion from function pointer to void*. So, when I compile the attached program with g++, I get: sp.cpp:22: instantiated from here /home/ghost/Work/boost/boost/shared_ptr.hpp:163: error: invalid conversion from `void (* const)()' to `void*' Is there any way to make it work? What I'm trying to do is: - access a function from DLL -- i.e. get shared_ptr<function_type> - do something with the function - cast the pointer into shared_ptr<void> The last pointer will be stored in various places to keep the DLL in memory until last object which depend on it is destroyed. I think I can keep shared_ptr<function_type> everywhere, but can shared_ptr<void> work somehow? Thanks, Volodya

Vladimir Prus wrote:
If I have boost::shared_ptr<some_class>, it's possible to cast it to shared_ptr<void>. But it does not appear to be any way to convert pointer to function to pointer to void -- just because there's no implicit conversion from function pointer to void*.
So, when I compile the attached program with g++, I get:
sp.cpp:22: instantiated from here /home/ghost/Work/boost/boost/shared_ptr.hpp:163: error: invalid conversion from `void (* const)()' to `void*'
Is there any way to make it work? What I'm trying to do is:
- access a function from DLL -- i.e. get shared_ptr<function_type> - do something with the function - cast the pointer into shared_ptr<void>
The last pointer will be stored in various places to keep the DLL in memory until last object which depend on it is destroyed.
I think I can keep shared_ptr<function_type> everywhere, but can shared_ptr<void> work somehow?
No, not directly. A pointer to a function cannot be converted to void*, not even with a reinterpret_cast, and shared_ptr doesn't support reinterpret_casts anyway. You can, however, hold the shared_ptr<F> itself in a shared_ptr<void>, at the expense of an additional memory allocation or two. shared_ptr<void> pv( new shared_ptr<F>(pf) ); // two allocs shared_ptr<void> pv( static_cast<void*>(0), bind( null_deleter(), pf ) ); // one If you don't need portability and you know that a function pointer and an object pointer have the same memory layout, you can reinterpret_cast a shared_ptr<F> to shared_ptr<void>&. If you use the deleter approach, you can later recover the original shared_ptr<F>: http://boost.org/libs/smart_ptr/sp_techniques.html#another_sp

Peter Dimov wrote:
Vladimir Prus wrote:
If I have boost::shared_ptr<some_class>, it's possible to cast it to shared_ptr<void>. But it does not appear to be any way to convert pointer to function to pointer to void -- just because there's no implicit conversion from function pointer to void*.
So, when I compile the attached program with g++, I get:
sp.cpp:22: instantiated from here /home/ghost/Work/boost/boost/shared_ptr.hpp:163: error: invalid conversion from `void (* const)()' to `void*'
Is there any way to make it work? What I'm trying to do is:
No, not directly. A pointer to a function cannot be converted to void*, not even with a reinterpret_cast, and shared_ptr doesn't support reinterpret_casts anyway.
I think if shared_ptr supported reinterpret_cast, I could use shared_ptr<void ()>.
You can, however, hold the shared_ptr<F> itself in a shared_ptr<void>, at the expense of an additional memory allocation or two.
shared_ptr<void> pv( new shared_ptr<F>(pf) ); // two allocs
Neat. I think this will work for me. I presume 'pf' is another shared_ptr<F> and I can write this: shared_ptr<void> foo() { shared_ptr<F> pf = ... return shared_ptr<void>(new shared_ptr<F>(pf)); } provides that usage count of 'pf' is exactly 1 when it's initialised?
shared_ptr<void> pv( static_cast<void*>(0), bind( null_deleter(), pf ) ); // one
And in this case original shared_ptr<F> will be deleted in destructor of the object returned by 'bind'. Even neater. Thanks! - Volodya
participants (2)
-
Peter Dimov
-
Vladimir Prus