Converting boost::shared_ptr< const T > to boost::shared_ptr< T >
Apologies, news editor != text editor (cntrl-enter != autocomplete). I have persistent objects in my appplication and their factory dishes out only constant references (more precisely only copies of a shared_ptr< const T >). In order to make the persistent objects writable, an underlying record needs to be locked in the RDBMS. A friend template instantiation (a WritablePointer< T >) controls this locking, and effectively gives non-const access to the persistent object. The WritablePointer's constructor takes a shared_ptr< const T >. What I want to be able to do is like this (with non-smart pointers): template< typename T > class WritablePointer { public: WritablePointer(const T* const p) : p_(const_cast< T* const >(p)) { p_->lock(); } // ... private: T *p_; }; I have: template< typename T > class WritablePointer { public: typedef typename boost::shared_ptr< T > SmartPointerType; typedef typename boost::shared_ptr< const T > ConstSmartPointerType; WritablePointer(const ConstSmartPointerType& p) : p_(static_cast< const SmartPointerType& >(p)) { p_->lock(); } private: SmartPointerType p_; }; This compiles under gcc 3.2.1 but with a warning: /usr/include/boost/shared_ptr.hpp:153: warning: invalid conversion from `const T* const' to `T*' /usr/include/boost/shared_ptr.hpp: In constructor [I have changed the concrete type from my application to T to simplify]. What I want to do is cast away the const-ness in exactly one place - the WritablePointer ctor. But because I get the warnings it's harder to spot truly illicit conversions. (I copied this technique from an article I read (on Dr. Dobb's or CUJ probably) which used volatile and a mutex to protect shared data between threads, and a smart pointer much like mine to provide write access. I'd be grateful for any suggestions. Alex
Alex Tibbles wrote:
Apologies, news editor != text editor (cntrl-enter != autocomplete).
I have persistent objects in my appplication and their factory dishes out only constant references (more precisely only copies of a shared_ptr< const T >). In order to make the persistent objects writable, an underlying record needs to be locked in the RDBMS. A friend template instantiation (a WritablePointer< T >) controls this locking, and effectively gives non-const access to the persistent object. The WritablePointer's constructor takes a shared_ptr< const T >. What I want to be able to do is like this (with non-smart pointers):
template< typename T > class WritablePointer { public: WritablePointer(const T* const p) : p_(const_cast< T* const >(p)) { p_->lock(); } // ... private: T *p_; };
I have:
template< typename T > class WritablePointer { public: typedef typename boost::shared_ptr< T > SmartPointerType; typedef typename boost::shared_ptr< const T > ConstSmartPointerType; WritablePointer(const ConstSmartPointerType& p) : p_(static_cast< const SmartPointerType& >(p)) { p_->lock(); } private: SmartPointerType p_; };
This compiles under gcc 3.2.1 but with a warning:
/usr/include/boost/shared_ptr.hpp:153: warning: invalid conversion from `const T* const' to `T*' /usr/include/boost/shared_ptr.hpp: In constructor
[I have changed the concrete type from my application to T to simplify].
What I want to do is cast away the const-ness in exactly one place - the WritablePointer ctor. But because I get the warnings it's harder to spot truly illicit conversions. (I copied this technique from an article I read (on Dr. Dobb's or CUJ probably) which used volatile and a mutex to protect shared data between threads, and a smart pointer much like mine to provide write access.
Interesting use case. You seem to need const_pointer_cast (currently only static_ and dynamic_pointer_cast are provided.) I'll probably add const_pointer_cast in the next release. In the meantime, you can use this (somewhat hacky) solution: WritablePointer(const ConstSmartPointerType& p): p_(reinterpret_cast< const SmartPointerType& >(p)) { p_->lock(); }
"Peter Dimov" wrote:
Alex Tibbles wrote: <snip>
Interesting use case. You seem to need const_pointer_cast (currently only static_ and dynamic_pointer_cast are provided.) I'll probably add const_pointer_cast in the next release.
In the meantime, you can use this (somewhat hacky) solution:
WritablePointer(const ConstSmartPointerType& p): p_(reinterpret_cast< const SmartPointerType& >(p)) { p_->lock(); } Thanks! I'll look forward to the next release. I did use a reinterpret_cast<> at some point but was trying to cut it out. At least I know that it's the only way at present, as I suspected, without code in Boost itself.
Thanks Alex
participants (2)
-
Alex Tibbles
-
Peter Dimov