[英]using unique_ptr with boost python - boost::shared_ptr works but unique_ptr doesnt
这可能与
Boost Python No to_python for std :: unique_ptr
但是,我没有看到任何响应,也不清楚这是“ boost-python”问题还是由于我对“ std :: unique_ptr”的特殊使用,我试图弄清楚为什么更改从boost派生的类:: shared_ptr在使用“ std :: unique_ptr []”时中断编译
下面是我的带有两个可能的'smart_array'类的boost python模块原始基于boost :: shared_array并且可以正常工作(如下所示)
当我使用基于unique_ptr(简单替换)的代码时,会出现令人困惑的编译错误。
// Boost Includes ==============================================================
#include <boost/python.hpp>
#include <boost/cstdint.hpp>
#define NO_BOOST
#ifdef NO_BOOST
#include "smart_array.h"
#else
#include "boost_smart_array.h"
#endif
template <class Numeric> class cic {
public:
smart_array<Numeric> nacc; //! Accumulators
cic(int s) : nacc(3) {
for (int i=0;i<3;i++) nacc[i] = (Numeric)0;
}
Numeric interpolate() { return(nacc[2]); }
};
// Using =======================================================================
using namespace boost::python;
BOOST_PYTHON_MODULE(cic_double)
{
class_< cic<double> >("cic_double", init< int >())
.def("interpolate", &cic<double>::interpolate);
}
-智能阵列类(原始-增强)
#include "boost/shared_array.hpp"
template<class T> class smart_array : public boost::shared_array<T> {
public:
//! Default constructor
smart_array() {}
//! Create an smart_array of size n
smart_array(long n) : boost::shared_array<T>(new T[n]) {
elements = n;
}
void resize(long n) {
elements = n;
boost::shared_array<T>::reset(new T[n]);
}
long len() const { return(elements); }
private:
long elements;
};
新增-基于unique_ptr
template<class T> class smart_array : public std::unique_ptr<T []> {
public:
//! Default constructor
smart_array() {}
//! Create an smart_array of size n
smart_array(long n) : std::unique_ptr<T []>(new T[n]) {
elements = n;
}
void resize(long n) {
elements = n;
std::unique_ptr<T []>::reset(new T[n]);
}
long len() const { return(elements); }
private:
long elements;
};
编译错误
[100%] Building CXX object CMakeFiles/cic_double.dir/py_cic_double.cpp.o
In file included from /Users/user/GitHubStuff/boost_cic_test/py_cic_double.cpp:2:
In file included from /usr/local/include/boost/python.hpp:18:
In file included from /usr/local/include/boost/python/class.hpp:23:
In file included from /usr/local/include/boost/python/object/class_metadata.hpp:11:
In file included from /usr/local/include/boost/python/object/value_holder.hpp:50:
In file included from /usr/local/include/boost/preprocessor/iteration/detail/iter/forward1.hpp:52:
/usr/local/include/boost/python/object/value_holder.hpp:135:11: error: no matching constructor for initialization of 'cic<double>'
: m_held(
^
/usr/local/include/boost/python/object/make_instance.hpp:71:30: note: in instantiation of function template specialization 'boost::python::objects::value_holder<cic<double> >::value_holder<boost::reference_wrapper<const cic<double> > >' requested here
return new (storage) Holder(instance, x);
^
/usr/local/include/boost/python/object/make_instance.hpp:45:22: note: in instantiation of member function 'boost::python::objects::make_instance<cic<double>, boost::python::objects::value_holder<cic<double> > >::construct' requested here
Derived::construct(&instance->storage, (PyObject*)instance, x)->install(raw_result);
^
/usr/local/include/boost/python/object/class_wrapper.hpp:29:30: note: in instantiation of function template specialization 'boost::python::objects::make_instance_impl<cic<double>, boost::python::objects::value_holder<cic<double> >, boost::python::objects::make_instance<cic<double>, boost::python::objects::value_holder<cic<double> > > >::execute<const boost::reference_wrapper<const cic<double> > >' requested here
return MakeInstance::execute(boost::ref(x));
^
/usr/local/include/boost/python/converter/as_to_python_function.hpp:27:72: note: in instantiation of member function 'boost::python::objects::class_cref_wrapper<cic<double>, boost::python::objects::make_instance<cic<double>, boost::python::objects::value_holder<cic<double> > > >::convert' requested here
convert_function_must_take_value_or_const_reference(&ToPython::convert, 1L);
^
/usr/local/include/boost/python/to_python_converter.hpp:88:22: note: in instantiation of member function 'boost::python::converter::as_to_python_function<cic<double>, boost::python::objects::class_cref_wrapper<cic<double>, boost::python::objects::make_instance<cic<double>, boost::python::objects::value_holder<cic<double> > > > >::convert' requested here
&normalized::convert
^
/usr/local/include/boost/python/object/class_wrapper.hpp:24:8: note: (skipping 2 contexts in backtrace; use -ftemplate-backtrace-limit=0 to see all)
struct class_cref_wrapper
^
/usr/local/include/boost/python/object/class_metadata.hpp:219:25: note: in instantiation of function template specialization 'boost::python::objects::class_metadata<cic<double>, boost::python::detail::not_specified, boost::python::detail::not_specified, boost::python::detail::not_specified>::register_aux2<cic<double>, boost::integral_constant<bool, false> >' requested here
class_metadata::register_aux2((T*)0, use_callback());
^
/usr/local/include/boost/python/object/class_metadata.hpp:205:25: note: in instantiation of member function 'boost::python::objects::class_metadata<cic<double>, boost::python::detail::not_specified, boost::python::detail::not_specified, boost::python::detail::not_specified>::register_aux' requested here
class_metadata::register_aux((T*)0);
^
/usr/local/include/boost/python/class.hpp:497:19: note: in instantiation of member function 'boost::python::objects::class_metadata<cic<double>, boost::python::detail::not_specified, boost::python::detail::not_specified, boost::python::detail::not_specified>::register_' requested here
metadata::register_(); // set up runtime metadata/conversions
^
/usr/local/include/boost/python/class.hpp:209:15: note: in instantiation of function template specialization 'boost::python::class_<cic<double>, boost::python::detail::not_specified, boost::python::detail::not_specified, boost::python::detail::not_specified>::initialize<boost::python::init_base<boost::python::init<int, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_> > >' requested here
this->initialize(i);
^
/Users/user/GitHubStuff/boost_cic_test/py_cic_double.cpp:24:2: note: in instantiation of function template specialization 'boost::python::class_<cic<double>, boost::python::detail::not_specified, boost::python::detail::not_specified, boost::python::detail::not_specified>::class_<boost::python::init<int, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_, mpl_::void_> >' requested here
class_< cic<double> >("cic_double", init< int >())
^
/Users/user/GitHubStuff/boost_cic_test/py_cic_double.cpp:11:32: note: candidate constructor (the implicit copy constructor) not viable: 1st argument ('typename reference_wrapper<const cic<double> >::type' (aka 'const cic<double>')) would lose const qualifier
template <class Numeric> class cic {
^
/Users/user/GitHubStuff/boost_cic_test/py_cic_double.cpp:14:2: note: candidate constructor not viable: no known conversion from 'typename reference_wrapper<const cic<double> >::type' (aka 'const cic<double>') to 'int' for 1st argument
cic(int s) : nacc(3) {
^
1 error generated.
make[3]: *** [CMakeFiles/cic_double.dir/py_cic_double.cpp.o] Error 1
make[2]: *** [CMakeFiles/cic_double.dir/all] Error 2
make[1]: *** [all] Error 2
make: *** [all] Error 2
不幸的是,目前尚无法使用boost :: python公开std::unique_ptr
,因为它需要移动语义,而boost :: python尚不支持这些语义( 此处有更多详细信息)。 此外,您不应从智能指针派生,因为这不是一个好习惯,并且它们没有虚拟析构函数(除了许多其他原因)
话虽如此,您还有很多其他选择,其中包括:
std::auto_ptr
作为数据成员, boost::python
很好地支持它(假设您的类不可复制)。 但是, auto_ptr
无法保存数组(它不会调用delete()
的正确变体)。 boost::shared_ptr
作为数据成员,并在API中隐藏其用法。 但是,请注意,出于上述相同的原因, boost::shared_ptr
也不能保存数组数据 。 std::vector<boost::shared_ptr<>>
,它将与使用vector_indexing_suite的 boost::shared_ptr
使用。 但是,还有许多其他方法,我个人建议重新设计您的代码,以使用来自boost :: python示例的一些更普遍接受的编码和python包装实践。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.