[C++-sig] make tupel/list convertible to class

David Abrahams dave at boost-consulting.com
Sun Dec 15 18:16:05 CET 2002


"Achim Domma" <achim.domma at syynx.de> writes:

> Hi,
>
> I have a class Color with different ctors. One of them is
> Color(int,int,int). If I now have a function 'void blabla(Color)' I want to
> make it callable from Python as 'blabla((10,20,30))'. What would be the best
> way to go?

So far there's no simple way to do this other than by adding a new
constructor to your C++ class which accepts a boost::python::tuple.
However, there have been multiple requests for something like this.
How does the following interface seem to you?

    namespace python = boost::python;

    void init_color(PyObject* self, python::tuple arg)
    {
        python::construct<Color>(
             self
             , boost::make_tuple(
                  python::extract<int>(arg[0])
                , python::extract<int>(arg[1])
                , python::extract<int>(arg[2]))
        );
    }


   ... 

    class_<Color>("Color", init<int,int,int>())
          .def("__init__", init_color)
          ...
          ;


Things to notice:

    * The argument to construct is Color.  To make it possible to
      construct objects containing smart pointers, such as
      auto_ptr<Color>, we'd need something like
      construct_ptr<auto_ptr<Color> > or something.  Fortunately,
      there's about to be no reason to ever hold the more-versatile
      boost::shared_ptr anyway, since we can now create shared_ptrs
      that manage the Python object and we'll soon be able to convert
      those back to Python seamlessly.

    * That's boost::make_tuple, not python::make_tuple.  Of course we
      need some way to pass C++ arguments on to the function which
      actually builds the C++ instance.

This example might be a little misleading because it appears to be
somewhat limited.  In fact, I'm suggesting that you could write
init_color so that it accepted any C++ arguments desired after the
obligatory "self" argument.  So this would give us a general way to
extend the __init__ interface of any wrapped C++ class beyond what's
provided by its constructors.

-- 
                       David Abrahams
   dave at boost-consulting.com * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution





More information about the Cplusplus-sig mailing list