gpt4 book ai didi

c++ - 如何用 Boost::python 包装派生模板类?

转载 作者:行者123 更新时间:2023-11-30 04:09:24 25 4
gpt4 key购买 nike

我有一个来自模板类的派生类:

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 创建一个类包装器,但我没有找到任何信息来编写模板类,只有模板函数。

我必须为每个基类定义一个类包装器吗?我是否需要为我的模板类中使用的每种类型定义一个类包装器?

最佳答案

RuntimeError发生是因为对 class_ 的要求的 Bases不满足模板参数:

A specialization of bases<...> which specifies previously-exposed C++ base classes of T

与先前曝光的是explained作为:

namespace python = boost::python;
python::class_<Base>("Base");
python::class_<Derived, python::bases<Base> >("Derived");

解决 RuntimeError ,或者:

  • 省略 bases如果公开的 API 不需要使用 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)

关于c++ - 如何用 Boost::python 包装派生模板类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21236890/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com