import polymorphism as plm
a = plm.mylist()
print(a)
a[0].print()
a[1].print()
这个脚本的输出是
[MyBase, MyDerived]
MyBase
MyBase
但预期产出是
[MyBase, MyDerived]
MyBase
MyDerived
因为mylist返回一个std::vector,其中包含一个派生类(MyDerived)的实例作为第二个成员。奇怪的是,当我将列表作为一个整体打印时,MyDerived会被识别出来。在
这里是C++代码的头文件:
^{pr2}$下面是cpp文件:
#include "polymorphism.hpp"
#include <iostream>
#include <pybind11/stl.h>
#include <pybind11/pybind11.h>
void MyBase::print() const
{ std::cout << "MyBase" << std::endl; }
void MyDerived::print() const
{ std::cout << "MyDerived" << std::endl; }
std::vector<MyBase*> mylist()
{
std::vector<MyBase*> list(2);
list[0] = new MyBase();
list[1] = new MyDerived();
return list;
}
PYBIND11_MODULE(polymorphism, m)
{
pybind11::class_<MyBase>(m, "MyBase")
.def(pybind11::init<>())
.def("print", &MyBase::print)
.def("__repr__", [](const MyBase &a) { return "MyBase"; });
pybind11::class_<MyDerived, MyBase>(m, "MyDerived")
.def(pybind11::init<>())
.def("print", &MyDerived::print)
.def("__repr__", [](const MyDerived &a) { return "MyDerived"; });
m.def("mylist", &mylist, "return a list");
}
编辑:更令人惊讶的是,当我移除MyDerived的“print”绑定时,我得到以下错误消息
[MyBase, MyDerived]
MyBase
Traceback (most recent call last):
File "test.py", line 8, in
a[1].print()
AttributeError: 'polymorphism.MyDerived' object has no attribute 'print'
这条消息似乎意味着MyDerived被很好地识别,而调用了错误的print版本(如果我理解得很好的话)。在
编辑2:这是一个使用蹦床类的版本。然而,这个版本会导致同样的错误输出。在
/* polymorphism.hpp */
#ifndef POLYMORPHISM_HPP
#define POLYMORPHISM_HPP
#include <vector>
#include <pybind11/stl.h>
#include <pybind11/pybind11.h>
class MyBase
{
public:
virtual void print() const;
};
class MyDerived : public MyBase
{
public:
virtual void print() const;
};
std::vector<MyBase*> mylist();
class PyMyBase : public MyBase
{
public:
using MyBase::MyBase; // Inherit constructors
void print() const override { PYBIND11_OVERLOAD(void, MyBase, print ); }
};
class PyMyDerived : public MyDerived
{
public:
using MyDerived::MyDerived; // Inherit constructors
void print() const override { PYBIND11_OVERLOAD(void, MyDerived, print);}
};
#endif
下面是相应的cpp文件:
/* polymorphism.cpp */
#include "polymorphism.hpp"
#include <iostream>
void MyBase::print() const
{ std::cout << "MyBase" << std::endl; }
void MyDerived::print() const
{ std::cout << "MyDerived" << std::endl; }
std::vector<MyBase*> mylist()
{
std::vector<MyBase*> list(2);
list[0] = new MyBase();
list[1] = new MyDerived();
return list;
}
PYBIND11_MODULE(polymorphism, m)
{
pybind11::class_<MyBase, PyMyBase>(m, "MyBase")
.def(pybind11::init<>())
.def("print", &MyBase::print)
.def("__repr__", [](const MyBase &a) { return "MyBase"; });
pybind11::class_<MyDerived, PyMyDerived>(m, "MyDerived")
.def(pybind11::init<>())
.def("print", &MyDerived::print)
.def("__repr__", [](const MyDerived &a) { return "MyDerived"; });
m.def("mylist", &mylist, "return a list");
}
我不知道为什么,但是
pybind11
中的原始指针似乎有问题。如果将返回类型更改为vector<unique_ptr<MyBase>>
,则示例可以正常工作。下面的示例编译为python模块example
,并生成预期的输出。在示例.cpp:
python shell:
^{pr2}$相关问题 更多 >
编程相关推荐