pybind11与复杂类型的转换

2024-09-28 19:34:50 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在将一个代数系统从boost/python迁移到pybind11,其中大部分工作正常,只需要简单的修改。该系统还实现了其类型的复杂版本,其中实部和虚部是而不是数字类型(想想多项式或傅立叶级数)

如果我想这样做,在我阅读的文档中的任何地方都包括pybind11/complex.h(例如,文档的第11.1章)。我的问题是,当我这样做时,编译失败了。这种失败发生在试图将方法绑定到以某种形式返回复杂类型对象的python时。 如果我没有包含“pybind11/complex11”,编译会进行得很好,方法也会工作得很好,但我的一些测试在尝试从python复合体(例如,(1+0j))构建这样的对象时失败。它抱怨没有定义相应的构造函数,尽管存在通过“def(pybind11::init)”实现并使其可见的AC(complex)、AC(AC)和其他类型的构造函数

下面是一个可以看到编译失败的简单示例

#include "pybind11/pybind11.h"
#include "pybind11/complex.h"
#include <complex>
#include <iostream>


class A {

};


template <typename T>
T copy(T& x)
{
    return T(x);
}


using AC = std::complex<A>;


PYBIND11_MODULE(TESTA, m)
{
    pybind11::class_<AC> inst(m, "AC", "test for AC");
    inst.def(pybind11::init<>());
    inst.def("__copy__", &copy<AC>);
}

int main()
{
    std::cout << "Hello World!\n";
}

结果是:

1>------ Build started: Project: Pybindtest, Configuration: Debug Win32 ------
1>Pybindtest.cpp
1>C:\Python38\include\pybind11\complex.h(59,1): error C2440: 'type cast': cannot convert from '_Ty' to 'double'
1>        with
1>        [
1>            _Ty=A
1>        ]
1>C:\Python38\include\pybind11\complex.h(59,38): message : No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
1>C:\Python38\include\pybind11\complex.h(58): message : while compiling class template member function 'pybind11::handle pybind11::detail::type_caster<std::complex<A>,void>::cast(const std::complex<A> &,pybind11::return_value_policy,pybind11::handle)'
1>C:\Python38\include\pybind11\pybind11.h(159): message : see reference to function template instantiation 'pybind11::handle pybind11::detail::type_caster<std::complex<A>,void>::cast(const std::complex<A> &,pybind11::return_value_policy,pybind11::handle)' being compiled
1>C:\Python38\include\pybind11\cast.h(1946): message : see reference to class template instantiation 'pybind11::detail::type_caster<std::complex<A>,void>' being compiled
1>C:\Python38\include\pybind11\pybind11.h(100): message : see reference to class template instantiation 'pybind11::detail::argument_loader<T &>' being compiled
1>        with
1>        [
1>            T=AC
1>        ]
1>C:\Python38\include\pybind11\pybind11.h(63): message : see reference to function template instantiation 'void pybind11::cpp_function::initialize<Return(__cdecl *&)(T &),Return,T&,pybind11::name,pybind11::is_method,pybind11::sibling>(Func,Return (__cdecl *)(T &),const pybind11::name &,const pybind11::is_method &,const pybind11::sibling &)' being compiled
1>        with
1>        [
1>            Return=AC,
1>            T=AC,
1>            Func=AC (__cdecl *&)(AC &)
1>        ]
1>C:\Python38\include\pybind11\pybind11.h(1117): message : see reference to function template instantiation 'pybind11::cpp_function::cpp_function<T,T&,pybind11::name,pybind11::is_method,pybind11::sibling>(Return (__cdecl *)(T &),const pybind11::name &,const pybind11::is_method &,const pybind11::sibling &)' being compiled
1>        with
1>        [
1>            T=AC,
1>            Return=AC
1>        ]
1>D:\temp for tests\Pybindtest\Pybindtest.cpp(29): message : see reference to function template instantiation 'pybind11::class_<AC> &pybind11::class_<AC>::def<T(__cdecl *)(T &),>(const char *,Func &&)' being compiled
1>        with
1>        [
1>            T=AC,
1>            Func=AC (__cdecl *)(AC &)
1>        ]
1>D:\temp for tests\Pybindtest\Pybindtest.cpp(29): message : see reference to function template instantiation 'pybind11::class_<AC> &pybind11::class_<AC>::def<T(__cdecl *)(T &),>(const char *,Func &&)' being compiled
1>        with
1>        [
1>            T=AC,
1>            Func=AC (__cdecl *)(AC &)
1>        ]
1>C:\Python38\include\pybind11\complex.h(59,1): error C2660: 'PyComplex_FromDoubles': function does not take 1 arguments
1>C:\Python38\include\complexobject.h(47,24): message : see declaration of 'PyComplex_FromDoubles'
1>Done building project "Pybindtest.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

我知道它告诉我缺少转换等,但我也不想将任何东西转换为双精度。在上面的例子中,它应该转换成A,我认为这就是包含'pybind11/complex.h'应该做的

很可能我做错了什么,或者我错过了什么。 有什么建议吗

谢谢 哈特默斯


Tags: tomessageincludefunctiontemplateacclasspybind11