How to erase elements from boost::ptr_vector

前端 未结 6 1299
清歌不尽
清歌不尽 2021-01-12 13:52

So I\'m trying to get rid of my std::vector\'s by using boost::ptr_vector. Now I\'m trying to remove an element from one, and have the removed element deleted as well. The m

相关标签:
6条回答
  • 2021-01-12 14:36

    I think you want to call .release() on the vector instead of erase. That removes the entry and deletes the memory.

    See the section "New Functions" for details in the tutorial, or check the reference.

    Alternatively, you need to get an iterator to an element in order to call erase(), I'm ot sure an A* counts in terms of a ptr_vector.

    0 讨论(0)
  • 2021-01-12 14:44

    The semantics of ptr_vector are very similar to a regular vector. You have to find an element before you can erase it.

    0 讨论(0)
  • 2021-01-12 14:46

    Curious thing: STL::vector<> is a Random Access Container, meaning that it uses Random Access Iterators.

    So vec.erase(vec.begin()+N) will remove the element at index N.

    Note that doing so breaks the whole iterator meme and you can no longer trivially switch between vectors and lists...

    0 讨论(0)
  • 2021-01-12 14:49

    Well you can do that with a std::vector either.

    In both cases erase takes an iterator as a parameter.
    So before you can erase something from a vector (or a ptr_vector) you need to locate it.

    Also note that the ptr_vector treats its content as if you have stored an object not a pointer. So any searching is done via the object.

    So basically

     std::vector<A>       x;
     std::ptr_vector<A>   y;
    
     // These two object should behave in exactly the same way.
     // The ONLY difference is inserting values which for y are pointers.
     // Y take ownership of the pointer and all subsequent acesses to the
     // members of y look like they are objects
    

    Example:

    #include <boost/ptr_container/ptr_vector.hpp>
    #include <vector>
    
    class A
    { int m;
        public:
        A(int x):m(x)   {}
        bool operator==(A const& rhs)   {return m = rhs.m;}
    };
    
    int main()
    {
        boost::ptr_vector<A>    x;
        x.push_back(new A(1));
        x.erase(std::find(x.begin(),x.end(),A(1)));
    
    
        std::vector<A>          y;
        y.push_back(A(2));
        y.erase(std::find(y.begin(),y.end(),A(2)));
    
        // To find an exact pointer don't modify the equality.
        // Use find_if and pass a predicate that tests for a pointer
        A* a = new A(3);
        boost:ptr_Vector<A>     z;
        z.push_back(a);
        z.erase(std::find_if(y.begin(),y.end(),CheckPointerValue(a));
    }
    
    struct CheckPointerValue
    {
         CheckPointerValue(A* a):anA(a) {}
         bool operator()(A const& x)    { return &X == anA;}
         private:
            A* anA;
    };
    
    0 讨论(0)
  • 2021-01-12 14:56

    You can use erase_if template method.

    vec.erase_if( predicate() );
    
    0 讨论(0)
  • 2021-01-12 14:57

    You need to use the member erase_if method with a suitable predicate. There's no need to delete the pointer, the container has ownership.

    struct delete_a {
        bool operator()(boost::ptr_vector<A>::value_type inA) {
           return inA == a;
        }
    }
    
    vec.erase_if(delete_a());
    

    (note this is just an example chosen for simplicity, for such situation in real code I suppose one would write a suitable bind/equal_to combo, or use lambda)

    Or, as an alternative, call release on the correct iterator, if you still want to use the object.

    0 讨论(0)
提交回复
热议问题