如何清除从boost :: ptr_vector元素 [英] How to erase elements from boost::ptr_vector

查看:522
本文介绍了如何清除从boost :: ptr_vector元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我试图摆脱我的std :: vector的通过使用boost :: ptr_vector。现在,我想从一个删除一个元素,并有删以及被删除的元素。对我来说,最明显的事情是应该做:

  A级
{INT米; };提高:: ptr_vector< A> VEC;
A * A =新的A;
vec.push_back(一);
vec.erase(一);

但是,这甚至不会编译(参见下面的完整的错误消息)。我已经试过擦除/删除成语像我将在一个std ::矢量,但提振的所有算法:: ptr_vector变成是不同于的std ::矢量略有不同。

所以我的问题:


  • 如何从ptr_vector删除指针?

  • 请我仍然需要手动删除()的元素我删除?

编译器错误:

  1 GT; ------启动生成:项目:ptr_vector_test,配置:调试的Win32 ------
1>编译...
1> ptr_vector_test.cpp
1> C:\\用户\\ rvanhout \\ SVN \\干线\\第三方\\提升\\范围\\ const_iterator.hpp(37):错误C2825:'C':必须是一个类或命名空间,随后当::
1> C:\\用户\\ rvanhout \\ SVN \\干线\\第三方\\提升\\ MPL \\ eval_if.hpp(63):见参考文献类模板实例的boost :: range_const_iterator< C>'正在编译
1>同
1> [
1> C = A *
1> ]
1> C:\\用户\\ rvanhout \\ SVN \\干线\\第三方\\提升\\范围\\ iterator.hpp(63):见参考文献类模板实例的boost :: MPL :: eval_if_c< C,F1,F2>'正在编译
1>同
1> [
1> C =真,
1> F1 =的boost :: range_const_iterator< A *>中
1> F2 =的boost :: range_mutable_iterator< A * const的>
1> ]
1> C:\\用户\\ rvanhout \\ SVN \\干线\\第三方\\提升\\ ptr_container \\详细\\ reversible_ptr_container.hpp(506):见参考文献类模板实例的boost :: range_iterator< C>'正在编译
1>同
1> [
1> C = A * const的
1> ]
1&GT; C:\\ tmp目录\\ ptr_vector_test \\ ptr_vector_test.cpp(21):见参考函数模板实例化的boost :: void_ptr_iterator&LT; VoidIter,T&GT; boost::ptr_container_detail::reversible_ptr_container<Config,CloneAllocator>::erase<A*>(const范围和放大器;)正在编制
1&GT;同
1&GT; [
1&GT; VoidIter =的std :: _ Vector_iterator&LT;无效*,性病::分配器&LT;无效*&GT;&gt;中
1&GT; T = A,
1&GT;配置=的boost :: ptr_container_detail :: sequence_config&LT; A,性病::矢量&lt;无效*,性病::分配器&LT;无效*&GT;&GT;&gt;中
1&GT; CloneAllocator =的boost :: heap_clone_allocator,
1&GT;范围= A *
1&GT; ]
1&GT; C:\\用户\\ rvanhout \\ SVN \\干线\\第三方\\提升\\范围\\ const_iterator.hpp(37):错误C2039:'常量性:不是`全局命名空间''成员
1&GT; C:\\用户\\ rvanhout \\ SVN \\干线\\第三方\\提升\\范围\\ const_iterator.hpp(37):错误C2146:语法错误:缺少;前标识符型
1&GT; C:\\用户\\ rvanhout \\ SVN \\干线\\第三方\\提升\\范围\\ const_iterator.hpp(37):错误C2208:'的boost ::类型:没有成员使用此类型来定义
1&GT; C:\\用户\\ rvanhout \\ SVN \\干线\\第三方\\提升\\范围\\ const_iterator.hpp(37):致命错误C1903:无法从previous个错误恢复;正在停止编译
1&GT;生成日志保存在file:// C:\\ tmp目录\\ ptr_vector_test \\调试\\ BuildLog.htm
1&GT; ptr_vector_test - 5个错误,0警告(S)
==========生成:0成功,1失败,0了最新,0已跳过==========


解决方案

那么你可以做到这一点与一个std :: vector的要么。

在这两种情况下擦除花费一个迭代作为参数。结果
所以,如果你可以删除从矢量(或ptr_vector)东西,你需要找到它。

另外请注意,ptr_vector对待其内容,如果您有存储的对象不是一个指针。因此,任何搜索是通过对象来完成。

所以基本上

 的std ::矢量&lt; A&GT; X;
 的std :: ptr_vector&LT; A&GT; ÿ; //这两个对象应该表现在完全相同的方式。
 //唯一的区别是插入值这为y都是指针。
 // y拍摄指针的所有权和所有后续acesses到
 // Y的成员像它们是对象

例如:

 的#include&LT;升压/ ptr_container / ptr_vector.hpp&GT;
#包括LT&;矢量&GT;A级
{INT米;
    上市:
    A(INT X):M(X){}
    布尔运算符==(一个const&放大器; RHS){返回M = rhs.m;}
};诠释的main()
{
    提高:: ptr_vector&LT; A&GT; X;
    x.push_back(新A(1));
    x.erase(的std ::发现(x.begin(),x.end(),A(1)));
    的std ::矢量&lt; A&GT; ÿ;
    y.push_back(A(2));
    y.erase(的std ::发现(y.begin(),y.end(),A(2)));    //要找到一个确切的指针不修改的平等。
    //使用find_if并传递一个predicate,对于一个指针测试
    A * A =新的A(3);
    提高:ptr_Vector&LT; A&GT; Z者除外;
    z.push_back(一);
    z.erase(的std :: find_if(y.begin(),y.end(),CheckPointerValue(一));
}结构CheckPointerValue
{
     CheckPointerValue(A * A):ANA(一){}
     布尔运算符()(A常量和放大器,X){回报和放大器; X == ANA;}
     私人的:
        A *安娜;
};

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 most obvious thing to me was to do:

class A
{ int m; };

boost::ptr_vector<A> vec;
A* a = new A;
vec.push_back(a);
vec.erase(a);

But this won't even compile (see below for the full error message). I've tried the erase/remove idiom like I would on a std::vector but all the algorithms of boost::ptr_vector turn out to be slightly different from those in std::vector.

So my questions:

  • How do I remove a pointer from a ptr_vector?
  • Do I still need to manually delete() that element that I removed?

Compiler error:

1>------ Build started: Project: ptr_vector_test, Configuration: Debug Win32 ------
1>Compiling...
1>ptr_vector_test.cpp
1>c:\users\rvanhout\svn\trunk\thirdparty\boost\range\const_iterator.hpp(37) : error C2825: 'C': must be a class or namespace when followed by '::'
1>        c:\users\rvanhout\svn\trunk\thirdparty\boost\mpl\eval_if.hpp(63) : see reference to class template instantiation 'boost::range_const_iterator<C>' being compiled
1>        with
1>        [
1>            C=A *
1>        ]
1>        c:\users\rvanhout\svn\trunk\thirdparty\boost\range\iterator.hpp(63) : see reference to class template instantiation 'boost::mpl::eval_if_c<C,F1,F2>' being compiled
1>        with
1>        [
1>            C=true,
1>            F1=boost::range_const_iterator<A *>,
1>            F2=boost::range_mutable_iterator<A *const >
1>        ]
1>        c:\users\rvanhout\svn\trunk\thirdparty\boost\ptr_container\detail\reversible_ptr_container.hpp(506) : see reference to class template instantiation 'boost::range_iterator<C>' being compiled
1>        with
1>        [
1>            C=A *const 
1>        ]
1>        c:\tmp\ptr_vector_test\ptr_vector_test.cpp(21) : see reference to function template instantiation 'boost::void_ptr_iterator<VoidIter,T> boost::ptr_container_detail::reversible_ptr_container<Config,CloneAllocator>::erase<A*>(const Range &)' being compiled
1>        with
1>        [
1>            VoidIter=std::_Vector_iterator<void *,std::allocator<void *>>,
1>            T=A,
1>            Config=boost::ptr_container_detail::sequence_config<A,std::vector<void *,std::allocator<void *>>>,
1>            CloneAllocator=boost::heap_clone_allocator,
1>            Range=A *
1>        ]
1>c:\users\rvanhout\svn\trunk\thirdparty\boost\range\const_iterator.hpp(37) : error C2039: 'const_iterator' : is not a member of '`global namespace''
1>c:\users\rvanhout\svn\trunk\thirdparty\boost\range\const_iterator.hpp(37) : error C2146: syntax error : missing ';' before identifier 'type'
1>c:\users\rvanhout\svn\trunk\thirdparty\boost\range\const_iterator.hpp(37) : error C2208: 'boost::type' : no members defined using this type
1>c:\users\rvanhout\svn\trunk\thirdparty\boost\range\const_iterator.hpp(37) : fatal error C1903: unable to recover from previous error(s); stopping compilation
1>Build log was saved at "file://c:\tmp\ptr_vector_test\Debug\BuildLog.htm"
1>ptr_vector_test - 5 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

解决方案

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

这篇关于如何清除从boost :: ptr_vector元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆