Boost.Python 不匹配签名左值
Boost.Python did not match signature lvalue
我有一个类Foo
,其中包含一个我想公开的成员x
,但通过 getter 函数而不是属性。我刚刚发现了make_getter
,所以我想我会试一试:
#include <boost/python.hpp>
namespace py = boost::python;
struct Base {
int x;
};
struct Foo : Base {
Foo(int i): Base{i} { }
};
BOOST_PYTHON_MODULE(Foo)
{
py::class_<Foo>("Foo", py::init<int>())
.def_readonly("x", &Foo::x)
.def("getX", py::make_getter(&Foo::x))
;
}
但是,这将失败:
>>> import Foo
>>> f = Foo.Foo(42)
>>> f.x
42
>>> f.getX()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
Boost.Python.ArgumentError: Python argument types in
Foo.getX(Foo)
did not match C++ signature:
getX(Base {lvalue})
>>>
这个错误到底意味着什么?显然签名匹配!我该如何解决这个问题?
如果您仔细检查ArgumentError
异常,问题是,您正在使用Foo
调用getX()
:
>>> f.getX()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
Boost.Python.ArgumentError: Python argument types in
Foo.getX(Foo)
而您尝试访问的数据成员实际上是 Base
的成员:
did not match C++ signature:
getX(Base {lvalue})
Boost.Python 需要执行从左值Foo
到左值Base
的转换,而你实际上还没有告诉 Boost 它可以做到这一点。问题最终源于&Base::x
是int Base::*
而不是int Foo::*
,所以boost::python::make_getter
中的模板推导会生成一个采用Base
而不是Foo
的函数。
最简单的解决方案是确保将正确的指向成员的指针传递给make_getter
:
BOOST_PYTHON_MODULE(Foo)
{
py::class_<Foo>("Foo", py::init<int>())
.def_readonly("x", &Foo::x)
.def("getX", py::make_getter(static_cast<int Foo::*>(&Foo::x)))
;
}
有了这个演员表,一切正常:
>>> from Foo import Foo
>>> Foo(4).getX()
4
不过这有点乏味,所以你可以写一个快速的方法/宏来为你做这件事:
template <typename Derived, typename Base, typename T>
T Derived::* as_derived(T Base::*member) {
return static_cast<T Derived::*>(member);
}
#define AS_DERIVED(CLS, FIELD) as_derived<CLS>(&CLS::FIELD)
你可以用它做:
BOOST_PYTHON_MODULE(Foo)
{
py::class_<Foo>("Foo", py::init<int>())
.def_readonly("x", &Foo::x)
.def("getX", py::make_getter(AS_DERIVED(Foo, x)))
;
}
<小时 />或者,你可以直接告诉Boost.Python层次结构:
BOOST_PYTHON_MODULE(Foo)
{
py::class_<Base>("Base", py::no_init)
.def("getX", py::make_getter(&Base::x))
;
py::class_<Foo, py::bases<Base>>("Foo", py::init<int>())
.def_readonly("x", &Foo::x)
;
}
这样,Foo
继承了getX()
,一切都很好。
相关文章:
- Qt SQLite没有查询或参数计数不匹配
- 模板参数推导失败,函数参数/参数不匹配
- 在使用累加时,C++中的运算符+不匹配
- C++ 与操作员不匹配<<
- 在 Arduino 上使用 sscanf 会导致与 const char * 不匹配,并且返回值始终相同,尽管输入值不同
- 与'operator='不匹配(操作数类型'String'且"void")
- C++模板/别名 - 模板参数列表中参数 1 处的类型/值不匹配
- C4018:类内有符号、无符号不匹配
- 我在 .h 中有一个枚举类,并且在.cpp错误中有一个运算符重载:与"运算符<<不匹配
- 为什么我收到错误:"运算符<<不匹配?
- RE2 不匹配非 ASCII 字符
- Python 参数类型与C++签名不匹配
- 提升 Python 包装的虚拟类 - 子类返回错误:与C++签名不匹配
- 将构造函数添加到boost.python子类导致参数不匹配错误
- boost.python:参数类型与C++签名不匹配
- 使用使用 Boost 生成的 Python 模块:与C++签名不匹配
- C++运行时类型与 Python 模块不匹配
- c++中的Xgboost负载模型(python ->c++预测分数不匹配)
- Boost Python签名不匹配问题
- Boost.Python 不匹配签名左值