[C++-sig] tuples::tuple -> python::tuple

Andreas Beyer mail at a-beyer.de
Wed May 3 10:19:14 CEST 2006


Hi François,

Thank you very much!


François Duranleau wrote:

> On Tue, 2 May 2006, Andreas Beyer wrote: 

[...]

>> When compiling the eample with this additional change, I get the
>> following error message:
>>
>> tuple_test.cpp:13: error: conversion from 
>> `boost::python::api::object' to
>>   non-scalar type `boost::python::tuple' requested
>>
>> which refers to the above line of code. I don't understand the message,
>> because both python::make_tuple() and my::tuple_to_python() return
>> python::tuple and not python::object.
>
>
> I see the problem. operator+ is inherited from boost::python::object 
> (actually, boost::python::api::object), and it returns a 
> boost::python::object. However, there is not implicit conversion from 
> that type to boost::python::tuple, but you can use an explicit one, e.g.:

[...]

>
> Actually, you don't really need that convertion in this application, 
> you could simply write my::tuple_to_python as
>
> template <class H, class T>
> python::object tuple_to_python(tuples::cons<H,T> const& x)
> {
>     // Here is the explicit conversion
>     return python::make_tuple(x.get_head()) +
>            my::tuple_to_python(x.get_tail());
> }
>
> and that's it.


This solves the problem in a very elegant way!

Just for the records, here is the complete working example (@Dave: Maybe 
such converter could go into the next release of boost::python?):

--- begin file ---

#include <boost/python.hpp>
#include <boost/tuple/tuple.hpp>

using namespace boost;

namespace my
{
   template <class H, class T>
   python::object tuple_to_python(tuples::cons<H,T> const& x)
   {
       // operator+ creates python::api::object
        return python::make_tuple(x.get_head()) + 
my::tuple_to_python(x.get_tail());
   }

   python::object tuple_to_python(tuples::null_type)
   {
        return python::tuple();
   }

   template <class T>
   struct tupleconverter
   {
        static PyObject* convert(T const& x)
        {
            return python::incref(my::tuple_to_python(x).ptr());
        }
   };
 
}

// an example how to use the tuple converter:

typedef tuples::tuple<int, double> a_tuple;
a_tuple get_a_tuple(int a, double b) {
    return a_tuple(a, b);
}

BOOST_PYTHON_MODULE(tuple_test) {  
   python::to_python_converter<a_tuple, my::tupleconverter<a_tuple> >();
   python::def("get_a_tuple", &get_a_tuple);
}

--- end file ---

-- 
Dr. Andreas Beyer
mail at a-beyer.de
www.andreas-beyer.de




More information about the Cplusplus-sig mailing list