Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
带函数模板的Python类:如何从外部添加实例? 总结 是否有一种方法(在C++中,而不是在Python中)为Boox::Python中的类添加额外的函数模板实例化(通过注入、重新打开定义、注册所需实例等)?< /P> 背景_Python_C++_Templates_Boost_Export - Fatal编程技术网

带函数模板的Python类:如何从外部添加实例? 总结 是否有一种方法(在C++中,而不是在Python中)为Boox::Python中的类添加额外的函数模板实例化(通过注入、重新打开定义、注册所需实例等)?< /P> 背景

带函数模板的Python类:如何从外部添加实例? 总结 是否有一种方法(在C++中,而不是在Python中)为Boox::Python中的类添加额外的函数模板实例化(通过注入、重新打开定义、注册所需实例等)?< /P> 背景,python,c++,templates,boost,export,Python,C++,Templates,Boost,Export,给定一个包含函数模板成员的类(不是类模板),我想使用Boost::Python生成Python绑定 但是,在编写库时,我事先不知道将使用哪些模板参数调用成员函数。这意味着,我不能在Boost::Python类定义中列出它们 例子 假设我们有一个类class,它有函数模板(带重载),还有两个测试类SomeClass和OtherClass,如下所示: class AnotherClass { public: std::string Name() { return &q

给定一个包含函数模板成员的类(不是类模板),我想使用Boost::Python生成Python绑定

但是,在编写库时,我事先不知道将使用哪些模板参数调用成员函数。这意味着,我不能在Boost::Python类定义中列出它们

例子 假设我们有一个类
class
,它有函数模板(带重载),还有两个测试类
SomeClass
OtherClass
,如下所示:

class AnotherClass
{
public:
    std::string Name()
    {
        return "AnotherClass";
    }
};

add_to_the_class(AnotherClass);
// or
add_to_class_definition<AnotherClass>("TheClass");
// or whatever works...
类定义 由此得出:

Called Foo(SomeClass)
Called Foo(OtherClass)
Called Bar(SomeClass, 42)
Called Bar(OtherClass, 42)
Called Bar(SomeClass, Hello World)
Called Bar(OtherClass, Hello World)
问题: 在本例中,Foo()和Bar()函数模板的实例化是在Boost::Python类定义中创建的(请参见源代码中的注释)。这意味着,如果不修改这段代码,库的用户就不能添加新的实例化

因此,我所寻找的是一种方法

  • 从Boost::Python类定义的外部“注入”这些实例化
  • 以某种方式重新打开定义
  • 在调用Boost::Python类定义之前,在某处注册所需的实例化
最后,库的用户应该能够执行以下操作:

class AnotherClass
{
public:
    std::string Name()
    {
        return "AnotherClass";
    }
};

add_to_the_class(AnotherClass);
// or
add_to_class_definition<AnotherClass>("TheClass");
// or whatever works...
另一个类
{
公众:
std::string Name()
{
返回“另一个类”;
}
};
将_添加到_类(另一个类);
//或
将“类”添加到“类”定义(“类”);
//或者任何有用的东西。。。

这有可能吗?有没有其他方法可以达到类似的效果?

过了一段时间,我找到了一个解决方案,并认为这对其他人来说可能也很有趣

解决方案 它实际上非常简单:
boost::python::class\uz
定义返回(当然)类型为
boost::python::class\uz
的类实例。这可以存储,因此我们可以稍后向其中添加成员定义:

static auto the_class_ = boost::python::class_< TheClass > ( "TheClass" )
    // add some .def(...) and so on here, if needed
;

template <class T>
void add_to_the_class()
{
    the_class_
        .def(
            "Foo",
            ( void ( TheClass::* )( T& ))( &TheClass::Foo ),
            ( boost::python::arg("arg") )
        )
        .def(
            "Bar",
            ( void ( TheClass::* )( T&, std::string ))( &TheClass::Bar ),
            ( boost::python::arg("arg"), boost::python::arg("param") )
        )
        .def(
            "Bar",
            ( void ( TheClass::* )( T&, int ))( &TheClass::Bar ),
            ( boost::python::arg("arg"), boost::python::arg("param") )
        )
    ;
}
static auto the\u class\uu=boost::python::class\uu(“TheClass”)
//如果需要,在这里添加一些.def(…)等等
;
模板
void将_添加到_类()
{
班_
def(
“福”,
(void(类::*)(T&)(类::Foo),
(boost::python::arg(“arg”))
)
def(
“酒吧”,
(void(类::*)(T&,std::string))(&TheClass::Bar),
(boost::python::arg(“arg”),boost::python::arg(“param”))
)
def(
“酒吧”,
(void(类::*)(T&,int))(&TheClass::Bar),
(boost::python::arg(“arg”),boost::python::arg(“param”))
)
;
}
现在,我们可以根据需要从外部向该定义添加任意多的额外重载:

add_to_the_class<AnotherClass>();
将_添加到_类();
这也消除了丑陋的宏

一些额外的见解 这一切都是有效的,因为到Python的实际绑定是在运行时创建的。在Posith::Python绑定代码中,实际上只定义了一些类和函数,这些函数和函数在主()之前调用,以启动C++代码和Python解释器之间的实际连接。 我认为,boost::python帮助中没有很好地记录这一点。我花了一段时间才弄明白。起初,我认为boost::python(通过一些模板魔术)会在编译时生成绑定。如果这是真的,上述解决方案将不起作用。事后看来,我现在完全明白了这一点

此外,这一见解(绑定是在运行时完成的,使用您提供的定义)还让我想到编写一个静态寄存器类,该类收集要导出到Python的类。这将进一步帮助我的库方法,因为我不必为每个新类扩展主
BOOST\u PYTHON\u模块
定义,而只需将类注册到静态寄存器(可能再次使用一些宏…)。但这是未来的工作。。。现在问题解决了

对于您的附带问题,提供了一种非侵入式扩展类的通用方法,同时避免重复代码。
static auto the_class_ = boost::python::class_< TheClass > ( "TheClass" )
    // add some .def(...) and so on here, if needed
;

template <class T>
void add_to_the_class()
{
    the_class_
        .def(
            "Foo",
            ( void ( TheClass::* )( T& ))( &TheClass::Foo ),
            ( boost::python::arg("arg") )
        )
        .def(
            "Bar",
            ( void ( TheClass::* )( T&, std::string ))( &TheClass::Bar ),
            ( boost::python::arg("arg"), boost::python::arg("param") )
        )
        .def(
            "Bar",
            ( void ( TheClass::* )( T&, int ))( &TheClass::Bar ),
            ( boost::python::arg("arg"), boost::python::arg("param") )
        )
    ;
}
add_to_the_class<AnotherClass>();