我有一个来自模板类的派生类:
template<typename X, typename Y>
class BaseFunction
{
static void export_BaseFunction()
{
?????
};
};
class Function : public BaseFunction<pair<double, double>, double>
{
Function() : BaseFunction<pair<double, double>, double>() {};
static void export_Function()
{
BaseFunction::export_BaseFunction();
boost::python::class_<Function, boost::python::bases<BaseFunction<pair<double, double>, double>>, boost::shared_ptr<Function>>("Function");
}
};
所以Boost::Python
要求我为BaseFunction创建一个类包装器,但是我没有找到任何写模板类的信息,只有模板函数。
我是否必须为每个基类定义一个类包装器?我是否要为模板类中使用的每种类型定义类包装器?
答案 0 :(得分:2)
发生RuntimeError
是因为未满足class_
的Bases
模板参数的要求:
的C ++基类
bases<...>
的特化,指定以前公开的T
以前曝光的explained为:
namespace python = boost::python;
python::class_<Base>("Base");
python::class_<Derived, python::bases<Base> >("Derived");
要解决RuntimeError
,请执行以下操作:
bases
和Function
执行向上转发或向下转发,则忽略BaseFunction<...>
信息。例如,如果没有任何暴露给Python的C ++函数的参数类型为BaseFunction<...>
或者将Function
对象作为BaseFunction<...>&
返回,那么Boost.Python不需要知道类型关系。否则,需要公开基类,Function
需要公开关系:
namespace python = boost::python;
typedef BaseFunction<pair<double, double>, double> function_base_type;
python::class_<function_base_type>("Base");
python::class_<Function, python::bases<function_base_type> >("Function");
注册BaseFunction
的特定类型实例时,字符串标识符必须是唯一的。
以下是Function
公开BaseFunction
的完整示例。 export_BaseFunction()
函数将检查它是否已经注册以防止有关重复转换的警告,并将使用C ++类型信息名称来消除BaseFunction
的不同模板实例之间的歧义。
#include <utility> // std::pair
#include <typeinfo> // typeid
#include <boost/python.hpp>
template<typename X, typename Y>
class BaseFunction
{
public:
static void export_BaseFunction()
{
// If type is already registered, then return early.
namespace python = boost::python;
bool is_registered = (0 != python::converter::registry::query(
python::type_id<BaseFunction>())->to_python_target_type());
if (is_registered) return;
// Otherwise, register the type as an internal type.
std::string type_name = std::string("_") + typeid(BaseFunction).name();
python::class_<BaseFunction>(type_name.c_str(), python::no_init);
};
};
class Function
: public BaseFunction<std::pair<double, double>, double>
{
private:
typedef BaseFunction<std::pair<double, double>, double> parent_type;
public:
static void export_Function()
{
// Explicitly register parent.
parent_type::export_BaseFunction();
// Expose this type and its relationship with parent.
boost::python::class_<Function, boost::python::bases<parent_type>,
boost::shared_ptr<Function> >("Function");
}
};
/// @brief Example function to demonstrate upcasting.
void spam(BaseFunction<std::pair<double, double>, double>&) {}
BOOST_PYTHON_MODULE(example)
{
Function::export_Function();
boost::python::def("spam", &spam);
}
交互式使用:
>>> import example
>>> f = example.Function()
>>> f
<example.Function object at 0xb7ec5464>
>>> example.spam(f)