pybind11中implicitly_convertible隐式转换不生效如何解决?
pybind11隐式转换功能实现报错修复
问题场景
实现pybind11的隐式转换最简示例时,代码编译正常但运行报错,相关代码如下:
C++绑定代码(example.cpp)
#include <pybind11/pybind11.h> namespace py = pybind11; class B { public: int b; }; class A { public: int a; A(int a) :a(a) {} A(B b) { a = b.b; } }; void fn(A) {} PYBIND11_MODULE(example, m) { py::class_<A>(m, "A") .def( py::init<int>(), py::arg("a") = 1 ); py::class_<B>(m, "B") .def( py::init<int>(), py::arg("b") = 2 ); py::implicitly_convertible<A, B>(); m.def("fn", &fn, py::arg("a") ); }
测试Python代码(test.py)
from example import * a = A() b = B() fn(b)
运行报错信息
$ python3.9 test.py Traceback (most recent call last): File "/pybindtest/test.py", line 8, in <module> fn(b) TypeError: fn(): incompatible function arguments. The following argument types are supported: 1. (a: example.A) -> None Invoked with: <example.B object at 0x7fc3016a83b0>
错误原因
存在两处配置错误:
- 没有给A类绑定接收B类型参数的构造函数,pybind11无法识别A可从B构造的逻辑
py::implicitly_convertible的模板参数顺序错误,该接口的参数规则为py::implicitly_convertible<源类型, 目标类型>(),原代码写反了转换方向,无法实现B转A的隐式转换
修正方案
对PYBIND11_MODULE部分的代码做两处修改:
- 给A类的绑定添加B参数构造函数的声明
- 调换隐式转换的模板参数顺序
修正后的绑定代码片段如下:
PYBIND11_MODULE(example, m) { py::class_<A>(m, "A") .def( py::init<int>(), py::arg("a") = 1 ) // 新增:绑定A从B构造的构造函数 .def(py::init<B>()); py::class_<B>(m, "B") .def( py::init<int>(), py::arg("b") = 2 ); // 修改:调换模板参数顺序,源类型为B,目标类型为A py::implicitly_convertible<B, A>(); m.def("fn", &fn, py::arg("a") ); }
修改后重新编译运行test.py即可正常执行。
内容的提问来源于stack exchange,提问作者mqnc
相关产品推荐
相关产品推荐

