BOOST_FOREACH Iterate over boost :: shared_ptr <list>

I am doing something similar to this element. Fixed the use of BOOST_FOREACH?

However, my returned list is wrapped in boost :: shared_ptr. If I do not assign the list to a variable before the BOOST_FOREACH loop, I get a crash at runtime because the list is being destroyed because it is temporary.

boost::shared_ptr< list<int> > GetList() { boost::shared_ptr< list<int> > myList( new list<int>() ); myList->push_back( 3 ); myList->push_back( 4 ); return myList; } 

Then later ..

 // Works if I comment out the next line and iterate over myList instead // boost::shared_ptr< list<int> > myList = GetList(); BOOST_FOREACH( int i, *GetList() ) // Otherwise crashes here { cout << i << endl; } 

I would like to be able to use the above without introducing the myList variable. Is it possible?

+7
source share
2 answers

Well, the "Best Practice" for shared_ptr mentions to avoid using unnamed temporary files:

http://www.boost.org/doc/libs/release/libs/smart_ptr/shared_ptr.htm#BestPractices

Avoid using unnamed shared_ptr temporary files to save input; see why it is dangerous, think about it Example:

 void f(shared_ptr<int>, int); int g(); void ok() { shared_ptr<int> p(new int(2)); f(p, g()); } void bad() { f(shared_ptr<int>(new int(2)), g()); } 

The ok function corresponds to the manual for the letter, while the poor constructions are temporary shared_ptr in place, allowing the memory to leak. Since function arguments are evaluated in an unspecified order, it is possible for a new int (2) to be evaluated first by g (), and we may never get into the shared_ptr constructor if g throws an exception.

The exception safety issue described above can also be fixed using the make_shared or allocate_shared factory functions defined in boost / make_shared.hpp. These factory functions also provide efficiency in consolidating distributions.

+2
source

You need to use:

 T* boost::shared_ptr<T>::get() 

Example:

 BOOST_FOREACH( int i, static_cast< list<int> >( *(GetList().get()) ) ) { } 

The problem is that you cannot cast boost :: shared_ptr and hope that it returns the underlying object that it stores. If that were true, then there would be no way to dereference a pointer to boost :: shared_ptr. You need to use the special :: get () method to return the object saved by boost :: shared_ptr, and then dereference it.

See http://www.boost.org/doc/libs/1_46_1/libs/smart_ptr/shared_ptr.htm#get for documentation.

0
source

All Articles