我有一些C ++数据结构,其中模板化的外部结构具有内部结构。根据模板参数,内部结构可能是也可能不是同一类型。当我使用boost.python将结构暴露给python时,我希望能够将内部类称为Outer.Inner。在我的boost.python暴露代码中,我应该只暴露每个不同的内部类型一次。我可以查询boost.python注册表以避免多次暴露同一个内部类,但我该怎么做才能使以前暴露的内部类成为其外部类的属性?考虑到这个被剥离的例子,问题可能会更清楚:
#include <boost/python.hpp>
struct inner {
};
template< typename T >
struct outer {
typedef inner inner_t;
static const char * name();
static
void expose() {
using namespace boost::python;
class_< outer< T > > outer_class( name() );
// check if inner type is in registry already
const type_info inner_info = boost::python::type_id< inner_t >();
const converter::registration * inner_registration
= boost::python::converter::registry::query( inner_info );
if( inner_registration == 0 || inner_registration->m_to_python == 0 ) {
// not already in registry
scope outer_scope( outer_class );
class_< inner_t > inner_class( "Inner" );
} else {
// already in registry because exposed via different outer
// what to put here? In python we need Outer.Inner to exist
}
}
};
template<>
const char *
outer< int >::name() { return "IntOuter"; }
template<>
const char *
outer< double >::name() { return "DoubleOuter"; }
BOOST_PYTHON_MODULE( inner_classes )
{
outer< int >::expose();
outer< double >::expose();
}
这是我想要运行的python代码:
import inner_classes as IC
IC.IntOuter.Inner
IC.DoubleOuter.Inner
为了完整性,这里有一个Jamroot来编译上面的内容:
import python ;
use-project boost : $(BOOST_ROOT) ;
project : requirements <library>/boost/python//boost_python ;
python-extension inner_classes : inner-classes.cpp ;
install install
: inner_classes
: <install-dependencies>on <install-type>SHARED_LIB <install-type>PYTHON_EXTENSION
<location>.
;
local rule run-test ( test-name : sources + )
{
import testing ;
testing.make-test run-pyd : $(sources) : : $(test-name) ;
}
run-test test : inner_classes test_inner_classes.py ;
答案 0 :(得分:0)
事实证明,一旦你知道boost.python的常见情况,这是非常简单的。在python这工作:
IC.DoubleOuter.Inner = IC.IntOuter.Inner
但不是我想要的解决方案。在C ++中,这有效:
scope outer_scope( outer_class );
outer_scope.attr( "Inner" ) = handle<>( inner_registration->m_class_object );
我已经尝试但没有意识到我需要将类对象包装在句柄&lt;&gt;中。