BOOST_FOREACH Итерация над Boost :: shared_ptr <list> - PullRequest
7 голосов
/ 04 июля 2011

Я делаю что-то похожее на этот элемент Правильное использование BOOST_FOREACH?

Однако мой возвращенный список обернут в boost :: shared_ptr.Если я не назначу список переменной до цикла BOOST_FOREACH, я получаю сбой во время выполнения, поскольку список разрушается, поскольку он временный.

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;
}

Потом позже ..

// 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;
}

Я бы хотел использовать вышесказанное, не вводя переменную myList.Это возможно?

Ответы [ 2 ]

2 голосов
/ 04 июля 2011

Хорошо, в «Наилучшей практике» для shared_ptr упоминается, что следует избегать использования неназванных временных:

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

Избегайте использования неназванного shared_ptr временные рамки для сохранения набора текста; чтобы понять почему это опасно, учтите это Пример:

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()); }

Функция ok следует за рекомендациями к письму, тогда как плохие конструкции временный shared_ptr на месте, допуская возможность памяти протечь. Поскольку аргументы функции оценивается в неуказанном порядке, это возможно, что новый int (2) будет оценивается первым, g () вторым, и мы может никогда не добраться до shared_ptr конструктор, если g выдает исключение.

Проблема безопасности исключений, описанная выше, также может быть устранена с помощью заводских функций make_shared или allocate_shared, определенных в boost / make_shared.hpp. Эти заводские функции также обеспечивают повышение эффективности за счет консолидации распределений.

0 голосов
/ 04 июля 2011

Вам нужно использовать:

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

Пример:

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

}

Проблема в том, что вы не можете разыменовать boost :: shared_ptr и надеетесь, что он возвращает базовый объект.магазины.Если бы это было так, то не было бы никакого способа разыменовать указатель на boost :: shared_ptr.Вам нужно использовать специализированный метод :: get (), чтобы вернуть объект, сохраненный в boost :: shared_ptr, и затем разыменовать его.

См. http://www.boost.org/doc/libs/1_46_1/libs/smart_ptr/shared_ptr.htm#get для документации.

...