[C++-sig] Retrieving lvalues using custom converters

Ralf W. Grosse-Kunstleve rwgk at yahoo.com
Wed Oct 1 01:50:36 CEST 2008

> void do_something( array_t &a ) { ... }
> then, boost.python complains that no converter is found. Now, if the argument
> "a" above to do_something needs to be modified, an ugly const_cast is
> required. Alternatively, one could do something like the following:
> void do_something( boost::python::object &obj )
> {
>   array_t a = boost::python::extract<array_t>( obj );
>   ...
> }

If the above works, this should work, too:

void do_something( array_t a ) { ... }

> The above works reasonably well in the absence of function overloading. In
> essence, the dispatch is now handled manually instead of using boost.python.
> But this approach breaks down in the presence of function overloading because
> we then start needing another intermediate function to dispatch:
> int do_something( array1_t & ) { ... }
> float do_something( array2_t & ) { ... }
> return_type do_something_dispatcher( object &o ) { /*dispatch by type in o*/ }

extract<> is a two stage process. Your code above is a shortcut for

    array_t a = boost::python::extract<array_t>( obj )();

The intermediate object has a .check() method to determine if the
conversion can succeed. You can use this two test for array1_t and


> However, this new dispatcher still has a problem with different return types
> which I don't know how to solve (short of converting the return type to a
> boost::python::object).

Yes, make your dispatcher return a boost::python::object.

> The problems above can be avoided if boost.python would allow extraction of
> lvalues for objects with custom from_python converters. Is this already
> possible


> and have I just missed it in the documentation?


> Or is extraction of lvalues possible using custom call_policies?


In my own code, I have an array ref<> type, which give you the .begin()
and .size(), but not any of the functions that change the size of the
array. I have custom converters from the main (reference-counted) array
type to ref<>, which I can pass via
  ref<> const&
and I can still modify the array elements.


More information about the Cplusplus-sig mailing list