[C++-sig] std::complex vs python complex

Holger Brandsmeier brandsmeier at gmx.de
Thu Apr 12 18:57:12 CEST 2012


Jim,

I didn't implement my own `version of std::complex` I just exported
`std::complex` as my own class. I only later found out that this type
is already exported by boost::python itself. I just stopped exporting
`std::complex` by myself which mostly works.

I am not fully happy with the situation as I also export
`std::complex<dd_real>` and `std::complex<qd_real>` which are complex
variables build upon 128bit and 256bit doubles. For consistency I
would like to treat complex numbers with 64bit, 128bit and 256bit
doubles all the same and to completely ignore python's own `complex`
type. That way I avoid problems where parts of the code work for 64bit
complex numbers but fail to work once I switch to 128bit. It is
probably difficult to stop boost::python from its special treatment of
`std::complex` and how it ties this to python's `complex`, so I will
have to live with the current situation.

-Holger

On Tue, Apr 10, 2012 at 17:37, Jim Bosch <talljimbo at gmail.com> wrote:
> On 04/10/2012 06:58 AM, Holger Brandsmeier wrote:
>>
>> Dear list,
>>
>> I exported a wrapper for std::complex<double>  to python and I am
>> willing to always use this class in python and I never want to use
>> pythons own `complex` data type.
>>
>> However, a funny thing happens when I export the addition operator
>> (the implemenation is given in the STL ...)
>>         .def(self + self)
>>
>> Now I get that:
>> type(scalar_cd(1,2) + scalar_cd(1,2))
>> <type 'complex'>
>>
>> But my own type is of the form:
>> type(scalar_cd(1,2))
>> <class 'parfem.scalarPy.scalar_cd'>
>>
>>
>> Why did this happen and how can I avoid this? Later own I get problems
>> when I want to pass this back to C++.
>>
>> I remember that pythons own complex type is a bit special and does not
>> cooperate nicely with boost::python and std::complex<>  but how did
>> python/boost::python end up converting the result of the addition to
>> `complex`?
>>
>> I am using:
>> Python 2.7.2
>> boost-1.46.1
>>
>
> Does your custom complex type provide implicit conversion to std::complex?
>
> If so, I'm guessing there's something going wrong with overload resolution;
> Boost.Python's operator wrappers simply invoke the C++ operators and lookup
> the Python conversion based on the result type. You can test this yourself
> with something like this:
>
> --------------------------------------------------------------------
>
> // use any namespace other than the one your classes are defined in
> namespace {
>
> template <typename T> void test_expr(T const & x) {
>    std::cerr << typeid(x).name() << std::endl;
> }
>
> } // <anonymous>
>
> int main() {
>    test_expr(whatever::scalar_cd(1,2) + whatever::scalar_cd(1,2));
>    return 0;
> }
>
> --------------------------------------------------------------------
>
> If the output you see when running the above is std::complex, you'll have a
> test case that doesn't involve Boost.Python you can use to debug your
> overload resolution.  If not, let me know, and I'll dig deeper into what
> Boost.Python's doing.
>
> HTH!
>
> Jim
> _______________________________________________
> Cplusplus-sig mailing list
> Cplusplus-sig at python.org
> http://mail.python.org/mailman/listinfo/cplusplus-sig


More information about the Cplusplus-sig mailing list