[smart_ptr] Proposal to add opreator->() in class weak_ptr.

Let’s add this code into the weak_ptr: shared_ptr<element_type> operator-> () const // throws bad_weak_ptr when expired { shared_ptr<element_type> temp = lock(); if( !temp ) boost::throw_exception( boost::bad_weak_ptr() ); return temp; } New way of use weak_ptr: shared_ptr< MyClass > sp( new MyClass ); weak_ptr< MyClass > wp(sp); try { wp->Use1(); wp->Use2(); } catch( const exception& e ) { cout << e.what() << endl; } It seems to me, that my way is more convenient than old school: if(shared_ptr<MyClass> temp = wp.lock()) { temp->Use1(); temp->Use2(); } else cout << "Cannot use, already destroyed" << endl ; -- Sergey Ilyin (mailto:spb.serg@mail.ru)

Сергей Ильин wrote:
Let’s add this code into the weak_ptr:
shared_ptr<element_type> operator-> () const // throws bad_weak_ptr when expired { shared_ptr<element_type> temp = lock(); if( !temp ) boost::throw_exception( boost::bad_weak_ptr() ); return temp; }
New way of use weak_ptr: shared_ptr< MyClass > sp( new MyClass ); weak_ptr< MyClass > wp(sp); try { wp->Use1(); wp->Use2(); } catch( const exception& e ) { cout << e.what() << endl; }
It seems to me, that my way is more convenient than old school:
if(shared_ptr<MyClass> temp = wp.lock()) { temp->Use1(); temp->Use2(); } else cout << "Cannot use, already destroyed" << endl ;
The two have different semantics - the first can execute Use1 but then throw due to the pointee being destroyed before the call to Use2, whereas the second version either calls both or neither. In addition, this change encourages poor code (such as your example), where multiple shared_ptrs are created unnecessarily, and exceptions can occur at arbitrary points in a sequence of calls. Finally, a weak_ptr not being available isn't really an exceptional circumstance, and if you really want to avoid the if, you can write something like: template <class T> shared_ptr<T> throw_lock(weak_ptr<T> const& p) { shared_ptr<T> temp(p); if(!temp) boost::throw_exception(boost::bad_weak_ptr()); return temp; } then do: throw_lock(wp)->Use1(); throw_lock(wp)->Use2(); At least the problems are explicit in that version. All that said, operator-> might be a useful convenience for the case where you are making only a single call, or you don't care about exceptions or efficiency, but the problem is that people may start to use it in all cases. Tom

Tom Widmer wrote:
All that said, operator-> might be a useful convenience for the case where you are making only a single call, or you don't care about exceptions or efficiency, but the problem is that people may start to use it in all cases.
This proposal seems to come up about once a month or so. Seems to me that we need to beef up the smart_ptr rationale section to explain better why it isn't a good idea. -- Jon Biggar Levanta jon@levanta.com 650-403-7252
participants (3)
-
Jonathan Biggar
-
Tom Widmer
-
Сергей Ильин