转换指针容器智能指针? [英] Convert container of pointers to smart pointers?

查看:194
本文介绍了转换指针容器智能指针?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有转换 STD 容器(如矢量)以简洁,通用的方式定期/哑指针:

 矢量< T *>

到,例如,的boost :: shared_ptr的

 矢量<提高:: shared_ptr的< T> >

我想我可以用把它关闭的范围内构造矢量

 矢量< T *> vec_a;
...
矢量<提高:: shared_ptr的< T> > vec_b(vec_a.begin(),vec_a.end());

但拒绝编译(Visual Studio 2008中)。

编辑:测试code:

 无效测试()
{
矢量<为int *> vec_a;
矢量<提高:: shared_ptr的< INT> > vec_b(vec_a.begin(),vec_a.end());
}

编译错误:

  1> C:\\ Program Files文件(x86)的\\微软的Visual Studio 9.0 \\ VC \\包括\\内存(131):错误C2664:'的std ::分配器< _Ty> ::构建:不能转换从参数2'诠释*'到'常量的boost :: shared_ptr的< T> &放大器;'
1>同
1> [
1> _Ty =升压:: shared_ptr的< INT>
1> ]
1>和
1> [
1> T = INT
1> ]
1>原因:无法从'诠释*'转换为'常量的boost :: shared_ptr的< T>'
1>同
1> [
1> T = INT
1> ]
1>构造类'的boost :: shared_ptr的< T>'声明为显性
1>同
1> [
1> T = INT
1> ]
1> C:\\ Program Files文件(x86)的\\微软的Visual Studio 9.0 \\ VC \\包括\\内存(822):见参考函数模板实例化_FwdIt的std :: _ Uninit_copy< INT ** _ FwdIt,_Alloc>(_ INIT,_init,_FwdIt ,_Alloc&安培;,的std :: _ Nonscalar_ptr_iterator_tag,性病:: _ Range_checked_iterator_tag)正在编制
1>同
1> [
1> _FwdIt =提高:: shared_ptr的< INT> *
1> _Alloc =的std ::分配器<提高:: shared_ptr的< INT>>中
1> _init = INT **
1> ]
1&GT; C:\\ Program Files文件(x86)的\\微软的Visual Studio 9.0 \\ VC \\包括\\向量(1141):见参考函数模板实例化_FwdIt stdext::unchecked_uninitialized_copy<_Iter,boost::shared_ptr<T>*,std::allocator<_Ty>>(_InIt,_InIt,_FwdIt,_Alloc &安培;)正在编制
1&GT;同
1&GT; [
1&GT; _FwdIt =提高:: shared_ptr的&LT; INT&GT; *
1&GT; _Iter =的std :: _ Vector_iterator&LT; INT *的std ::分配器&LT; INT *&GT;&gt;中
1&GT; T = INT,
1&GT; _Ty =提高:: shared_ptr的&LT; INT&gt;中
1&GT; _init =的std :: _ Vector_iterator&LT; INT *的std ::分配器&LT; INT *&GT;&gt;中
1&GT; _Alloc =的std ::分配器&LT;提高:: shared_ptr的&LT; INT&GT;&GT;
1&GT; ]
1&GT; C:\\ Program Files文件(x86)的\\微软的Visual Studio 9.0 \\ VC \\包括\\向量(956):见参考函数模板实例化的boost :: shared_ptr的&LT; T&GT; *的std ::矢量&lt;&_Ty GT; :: _ Ucopy&LT; _Iter&GT;(_ Iter项目,_Iter,提高:: shared_ptr的&LT; T&GT; *)正在编制
1&GT;同
1&GT; [
1&GT; T = INT,
1&GT; _Ty =提高:: shared_ptr的&LT; INT&gt;中
1&GT; _Iter =的std :: _ Vector_iterator&LT; INT *的std ::分配器&LT; INT *&GT;&GT;
1&GT; ]
1&GT; C:\\ Program Files文件(x86)的\\微软的Visual Studio 9.0 \\ VC \\包括\\向量(889):见参考函数模板实例化无效std::vector<_Ty>::_Insert<_Iter>(std::_Vector_const_iterator<_Ty,_Alloc>,_Iter,_Iter,std::forward_iterator_tag)'正在编译
1&GT;同
1&GT; [
1&GT; _Ty =提高:: shared_ptr的&LT; INT&gt;中
1&GT; _Iter =的std :: _ Vector_iterator&LT; INT *的std ::分配器&LT; INT *&GT;&gt;中
1&GT; _Alloc =的std ::分配器&LT;提高:: shared_ptr的&LT; INT&GT;&GT;
1&GT; ]
1&GT; C:\\ Program Files文件(x86)的\\微软的Visual Studio 9.0 \\ VC \\包括\\向量(537):见参考函数模板实例化无效std::vector<_Ty>::insert<_Iter>(std::_Vector_const_iterator<_Ty,_Alloc>,_Iter,_Iter)'正在编译
1&GT;同
1&GT; [
1&GT; _Ty =提高:: shared_ptr的&LT; INT&gt;中
1&GT; _Iter =的std :: _ Vector_iterator&LT; INT *的std ::分配器&LT; INT *&GT;&gt;中
1&GT; _Alloc =的std ::分配器&LT;提高:: shared_ptr的&LT; INT&GT;&GT;
1&GT; ]
1&GT; C:\\ Program Files文件(x86)的\\微软的Visual Studio 9.0 \\ VC \\包括\\向量(514):见参考函数模板实例无效的std ::矢量&lt; _Ty&GT; :: _构造&LT; _Iter&GT;(_ Iter项目,_Iter,STD :: input_iterator_tag)正在编制
1&GT;同
1&GT; [
1&GT; _Ty =提高:: shared_ptr的&LT; INT&gt;中
1&GT; _Iter =的std :: _ Vector_iterator&LT; INT *的std ::分配器&LT; INT *&GT;&GT;
1&GT; ]
1&GT; \\ TEST.CPP(8364):见参考函数模板实例化'的std ::矢量&lt; _Ty&GT; ::矢量&lt;的std :: _ Vector_iterator&LT; INT,_Alloc&GT;&GT;(_ Iter项目,_Iter)正在编制
1&GT;同
1&GT; [
1&GT; _Ty =提高:: shared_ptr的&LT; INT&gt;中
1&GT; _Alloc =的std ::分配器&LT; INT *&gt;中
1&GT; _Iter =的std :: _ Vector_iterator&LT; INT *的std ::分配器&LT; INT *&GT;&GT;
1&GT; ]


解决方案

联合 ::性病:: back_inserter ::性病::变换并执行转换一个小功能。如果还使用储备,这应该是相当有效的。一旦所有的模板展开,你会基本上得到这个code:

 模板&LT;类T&GT;
静态内嵌::性病:: TR1的:: shared_ptr的&LT; T&GT; to_shared_ptr(T * VAL)
{
   返回::性病:: TR1的:: shared_ptr的&LT; T&GT;(VAL);
}无效测试()
{
   ::性病::矢量&lt;为int *&GT; vec_a;
   ::性病::矢量&lt; ::性病:: TR1的:: shared_ptr的&LT; INT&GT; &GT; vec_b;
   vec_b.reserve(vec_a.size());
   ::性病::变换(vec_a.begin(),vec_a.end(),::性病:: back_inserter(vec_b)
                    to_shared_ptr&LT; INT&GT;);
   vec_a.clear();
}

Is there a concise, generic way to convert a std container (such as vector) of regular/dumb pointers:

vector< T* >

to, for instance, boost::shared_ptr?:

vector< boost::shared_ptr<T> >

I thought I could pull it off using vector's range constructor:

vector< T* > vec_a;
...
vector< boost::shared_ptr<T> > vec_b( vec_a.begin(), vec_a.end() );

but that refused to compile (Visual Studio 2008).

EDIT: Test code:

void test()
{
vector< int* > vec_a;
vector< boost::shared_ptr<int> > vec_b( vec_a.begin(), vec_a.end() );
}

Compilation errors:

1>c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\memory(131) : error C2664: 'std::allocator<_Ty>::construct' : cannot convert parameter 2 from 'int *' to 'const boost::shared_ptr<T> &'
1>        with
1>        [
1>            _Ty=boost::shared_ptr<int>
1>        ]
1>        and
1>        [
1>            T=int
1>        ]
1>        Reason: cannot convert from 'int *' to 'const boost::shared_ptr<T>'
1>        with
1>        [
1>            T=int
1>        ]
1>        Constructor for class 'boost::shared_ptr<T>' is declared 'explicit'
1>        with
1>        [
1>            T=int
1>        ]
1>        c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\memory(822) : see reference to function template instantiation '_FwdIt std::_Uninit_copy<int**,_FwdIt,_Alloc>(_InIt,_InIt,_FwdIt,_Alloc &,std::_Nonscalar_ptr_iterator_tag,std::_Range_checked_iterator_tag)' being compiled
1>        with
1>        [
1>            _FwdIt=boost::shared_ptr<int> *,
1>            _Alloc=std::allocator<boost::shared_ptr<int>>,
1>            _InIt=int **
1>        ]
1>        c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\vector(1141) : see reference to function template instantiation '_FwdIt stdext::unchecked_uninitialized_copy<_Iter,boost::shared_ptr<T>*,std::allocator<_Ty>>(_InIt,_InIt,_FwdIt,_Alloc &)' being compiled
1>        with
1>        [
1>            _FwdIt=boost::shared_ptr<int> *,
1>            _Iter=std::_Vector_iterator<int *,std::allocator<int *>>,
1>            T=int,
1>            _Ty=boost::shared_ptr<int>,
1>            _InIt=std::_Vector_iterator<int *,std::allocator<int *>>,
1>            _Alloc=std::allocator<boost::shared_ptr<int>>
1>        ]
1>        c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\vector(956) : see reference to function template instantiation 'boost::shared_ptr<T> *std::vector<_Ty>::_Ucopy<_Iter>(_Iter,_Iter,boost::shared_ptr<T> *)' being compiled
1>        with
1>        [
1>            T=int,
1>            _Ty=boost::shared_ptr<int>,
1>            _Iter=std::_Vector_iterator<int *,std::allocator<int *>>
1>        ]
1>        c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\vector(889) : see reference to function template instantiation 'void std::vector<_Ty>::_Insert<_Iter>(std::_Vector_const_iterator<_Ty,_Alloc>,_Iter,_Iter,std::forward_iterator_tag)' being compiled
1>        with
1>        [
1>            _Ty=boost::shared_ptr<int>,
1>            _Iter=std::_Vector_iterator<int *,std::allocator<int *>>,
1>            _Alloc=std::allocator<boost::shared_ptr<int>>
1>        ]
1>        c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\vector(537) : see reference to function template instantiation 'void std::vector<_Ty>::insert<_Iter>(std::_Vector_const_iterator<_Ty,_Alloc>,_Iter,_Iter)' being compiled
1>        with
1>        [
1>            _Ty=boost::shared_ptr<int>,
1>            _Iter=std::_Vector_iterator<int *,std::allocator<int *>>,
1>            _Alloc=std::allocator<boost::shared_ptr<int>>
1>        ]
1>        c:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\include\vector(514) : see reference to function template instantiation 'void std::vector<_Ty>::_Construct<_Iter>(_Iter,_Iter,std::input_iterator_tag)' being compiled
1>        with
1>        [
1>            _Ty=boost::shared_ptr<int>,
1>            _Iter=std::_Vector_iterator<int *,std::allocator<int *>>
1>        ]
1>        .\test.cpp(8364) : see reference to function template instantiation 'std::vector<_Ty>::vector<std::_Vector_iterator<int,_Alloc>>(_Iter,_Iter)' being compiled
1>        with
1>        [
1>            _Ty=boost::shared_ptr<int>,
1>            _Alloc=std::allocator<int *>,
1>            _Iter=std::_Vector_iterator<int *,std::allocator<int *>>
1>        ]

解决方案

Combine ::std::back_inserter with ::std::transform and a little function that will perform the conversion. If you also use reserve, this should be reasonably efficient. Once all the templates are expanded you will essentially get this code:

template <class T>
static inline ::std::tr1::shared_ptr<T> to_shared_ptr(T *val)
{
   return ::std::tr1::shared_ptr<T>(val);
}

void test()
{
   ::std::vector< int* > vec_a;
   ::std::vector< ::std::tr1::shared_ptr<int> > vec_b;
   vec_b.reserve(vec_a.size());
   ::std::transform(vec_a.begin(), vec_a.end(), ::std::back_inserter(vec_b),
                    to_shared_ptr<int>);
   vec_a.clear();
}

这篇关于转换指针容器智能指针?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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