Boost logo

Boost Users :

From: Sergey Sadovnikov (flex_ferrum_at_[hidden])
Date: 2008-05-05 05:36:22


Hi all.

There is an issue found with erase_if algorithm for ptr_list
container. Here is a bit of code:

class A;
boost::ptr_list<A> m_sheeps;
class A
{
public:
    A(int i) : m_i(i)
    {}
    operator int ()
    {
        return this->m_i;
    }
    void mydelete (int i)
    {
        m_sheeps.erase_if(std::bind2nd(std::less<int>(), i));
    }
public:
    int m_i;
};

//////////////////////////////////////////////////////////////////////////
int main()
{
    m_sheeps.push_back(new A(1));
    m_sheeps.push_back(new A(3));
    m_sheeps.push_back(new A(4));

    for (boost::ptr_list<A>::iterator iter = m_sheeps.begin(); iter != m_sheeps.end();)
    {
                std::cout << (*iter).m_i;
        (*iter++).mydelete(2);
        
    }
        
    return 0;
}

This code outputs following sequence to the console:
14
This sequence does not contains '3' because of erase_if modify
underlaying list container with stable_partition algorithm also.
If I replace boost::ptr_list to std::list the output will correct (i.
e. '134')
Main question is following: is such behavior correct for certain kind
of container? I suspect what ptr-containers preserve standard semantic of corresponded
standard containers. And erasing from the ptr_list does not invalidate
iterators to this list (exclude cases described in the Standard). Or ptr_list::erase_if algorithm does not preserve
semantic of ptr_list::remove_if algorithm? But there is nothing about
such behavior in the documentation.

PS: I know what erase_if algorithm has generic implementation (in the
ptr_sequence class) and has not special implementation for ptr_list.
But documentation has the following sentence:

"
Iterators are invalidated as in the corresponding standard container

Because the containers in this library wrap standard containers, the rules for invalidation of iterators are the same as the rules of the corresponding standard container.

For example, for both boost::ptr_vector<T> and std::vector<U> insertion and deletion only invalidates the deleted element and elements following it; all elements before the inserted/deleted element remain valid.
"
(http://www.boost.org/doc/libs/1_35_0/libs/ptr_container/doc/conventions.html#iterators-are-invalidated-as-in-the-corresponding-standard-container)

-- 
Best Regards
 Sergey                          mailto:flex_ferrum_at_[hidden]

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net