[C++-sig] Re: long long unsigned issue...

David Abrahams dave at boost-consulting.com
Sun Jun 8 14:11:05 CEST 2003


"Milind Patil" <milind_patil at hotmail.com> writes:

> "David Abrahams" <dave at boost-consulting.com> wrote in message
> news:uy90p3nmp.fsf at boost-consulting.com...
>> "Milind Patil" <milind_patil at hotmail.com> writes:
>>
>> My point is that this is a *very* big toy, with lots of
>> constructors which look like they could potentially contend for the
>> same input arguments.  Can't you reduce the problem you're having a
>> little bit more?
>
> Yes,  realize that the example class had lots of constructors. But the
> original class that I am wrapping is huge.  The constructor contention
> is part of my problem as I struggle to get types accross C++ and
> python to match up. I want my python wrapper to behave like the
> C++ class I am wrapping with very few caveats.

A noble goal, but I want to caution you that Python users generally
have different expectations from C++ users.

>> Do you need *implicit* conversion capability?  Remember that implicit
>> conversions are generally un-Pythonic.
>>
>
> I was trying to save myself the tiresome chore of writing operator .defs
> for the matrix of different types and operators that the class supports.
>
> For example
>
> .def( self + self)
>
> with
>
> implicity_convertible<char *, Y>();
> implicity_convertible<int, Y>();
> implicity_convertible<unsigned int, Y>();

Wow, your thing is really convertible from char* and int?  Spooky!
Note that on the Python side, int and unsigned int are both
represented by the same type of object, so getting both working is
generally not useful.  It will always pick the same one, depending on
which is registered first.

> would save me
>
> .def(self + other<char *>())
> .def(other<char *>() + self)
> .def(self + other<int>())
> .def(other<int> + self)
> .def(self + other<unsigned int>())
> ...

Yeah, but I guess there's a lot of ambiguity possible.  The behavior
will depend a lot on the order with which you register these
conversions.

> Isn't  this a common use case scenario for boost python -- Mapping
> C++ class which behaves like numeric types to python numeric
> type like behaviour?

Yep, but the Python numeric types generally don't behave that way.

>> > Now that we have a long_ to Y_Wrapper constructor
>> > and that class_ Y has Y_Wrapper as one of the bases
>>
>> You got that backwards.  Y is the base of Y_Wrapper.
>>
>
> My fault. I mistakenly thought that the  "class_< Y, Y_Wrapper >("Y", init<
>>())"
> part of module definition meant Y, and Y_Wrapper are bases of the python
> Y class.

A C++ class can't really be a base of a Python class.  What it means
is that when you construct a Python Y object from Python by invoking
Y(...), it will contain an instance of Y_Wrapper but be convertible to
Y, Y&, Y*,... on the C++ side in addition to Y_Wrapper, Y_Wrapper&,
...

If you didn't supply that Y_Wrapper argument, Python Y objects
constructed from Python would contain just a plain C++ Y object.

>> The right solution to this problem is to provide for something Ralf
>> has been requesting for some time:  the ability to inject new
>> constructors into a class, just the way we can inject methods that
>> aren't built from member functions.  Something like:
>>
>> Y Y_from_pylong(long_ y)
>> {
>>     return Y(extract<unsigned long long>(y));
>> }
>>
>>        ...
>>        .def("__init__", constructor(Y_from_pylong))
>>
>
> I think such a class constructor injector will really be useful for
> doing converters in a simple way.

We just need to arrange for time and/or funding to do it...

>> > a) Expose C++ classes as python classes alone. User will not derive
>> >     from the exposed classes.
>> > b) Expose C++ classes as derivable classes in python.
>>
>> a and b are equivalent as far as the library is concerned.
>>
>
> Isn't there a difference in how a user wraps a class with virtual
> functions and one without virtual functions

Yes, but you didn't mention virtual functions above.  You can derive
new Python classes from any Boost.Python class.

>  -- in the scenario where the user expects the python class to be
> extended? My interpretation of docs was that a Y_Wrapper class
> holding a PyObject* as a member is needed to wrap the Y class with
> virtual methods.
>
>> I'm confused.  Why do you want more info on c) if you don't use
>> Boost.Python that way?
>
> I do use the embedded + extension scenario. 

OK, I was confused because you said your use case was a) and d).

> I don't have to
> reference or derive from the python classes in the C++ that embeds
> the python extension and I don't have to derive from the c++ classes
> in python.

Well, I'm not sure I understand what you need, but if you ask
specific questions I can try to help.

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com





More information about the Cplusplus-sig mailing list