c++ - 将指针容器转换为智能指针?

标签 c++ pointers boost stl smart-pointers

是否有一种简洁、通用的方法来转换常规/哑指针的 std 容器(例如 vector):

vector< T* >

例如,boost::shared_ptr?:

vector< boost::shared_ptr<T> >

我想我可以使用 vector 的范围构造函数来完成它:

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

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

编辑:测试代码:

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

编译错误:

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>        ]

最佳答案

你可以使用std::transform:

  template <typename T>
  boost::shared_ptr<T> to_shared_ptr(T * p) { return boost::shared_ptr<T>(p); }

  vec_b.resize(vec_a.size());  
  std::transform(vec_a.begin(), vec_a.ebd(), vec_b.begin(), to_shared_ptr);

但是,建议的做法是在创建后立即将原始指针分配给智能指针。将原始指针放入容器中,然后将它们复制到另一个容器中看起来很危险。您需要确保没有其他人释放这些原始指针。您可以在传输后立即通过 vec_a.clear() 强调这一点 - 但这远不能保证。

关于c++ - 将指针容器转换为智能指针?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4787499/

相关文章:

c++ - 使用 boost 的 C++ 中的 hello world python 扩展?

c++ - 引用指向哪里?

c++ - 使用其指针从列表中删除项目

c++ - 使用 boost::program_options 禁止无符号值的负参数

c++ - 为什么将 int 向上移位会产生负数?

c++ - 如何计算指针的哈希值?

c - C中的指针转换代码是什么意思

c++ - 如何操作指向的字符串

c++ - boost.random buggy 警告 - 这是什么意思?

c++ - 在 Visual Studio 2010 中链接 boost 库时出现问题。