[C++-sig] Re: Boost.Python << & >> bug

David Abrahams dave at boost-consulting.com
Tue Aug 5 05:20:27 CEST 2003

"Niall Douglas" <s_sourceforge at nedprod.com> writes:

> On 3 Aug 2003 at 21:41, David Abrahams wrote:
>> > Enclosed is the condensed example as requested. 
>> I assume you're referring to the enclosure in the other message?
> Yeah my email program mangled it :(
>> No this is a failure of your wrapping code.  Very simply,
>>     class_< FX::FXId >("FXId", no_init)
>>         .def( other< FX::FXStream >() << self )
>>         .def( other< FX::FXStream >() >> self )
>> Attempts to wrap two operator expressions which take an FXStream on
>> the lhs and and FXId on the rhs.  But you don't have anything which
>> would match those expressions.  Try it:
>>       // C++ code
>>       FXStream x;
>>       FXId y;
>>       x << y;  // <== error
>>    friend FX::FXStream& operator<<(FX::FXStream& store,const FXId*
>>    obj){return store;} friend FX::FXStream& operator>>(FX::FXStream&
>>    store,FXId*& obj){return store;}
>> These declare operators which take an FXId* on the rhs:
>>       x << &y;
> Yeah sorry about that - I had actually corrected this but forgot to 
> recorrect it after another pyste cycle. However if you change the << 
> overload in FXId to take a reference, it's the same problem. See 
> attached.

That's the same problem we were having before: no support for
lvalues.  That's now fixed in CVS.  You can apply the enclosed patch
to try it.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: operators.patch
Type: text/x-patch
Size: 2100 bytes
Desc: not available
URL: <http://mail.python.org/pipermail/cplusplus-sig/attachments/20030804/f6cb8de5/attachment.bin>
-------------- next part --------------

>> > Here because FXStream does not provide an overload for anything in
>> > boost, it can't know it's really an unsigned char.
>> I don't know what that means either.
> I meant that the compiler when faced with "a << b" where there is no 
> direct overload for operator<<(a,b) must cast either a or b to 
> something else to find an overload which can accept them.

Don't know what you mean by "direct overload".

> I had assumed that boost.python provides template<class type> class 
> wrapper { ... operator type() const; in order for the wrapper classes 
> to cast down to their containing types 

Huh?  Sorry, you lost me.

> so that the overloads provided by the code being wrapped can do
> their work. Or I suppose the wrapper could also inherit publicly
> from the wrapped type, but this would probably be less flexible.

None of the above.

>> The problem you're seeing above may be due to a documentation bug on
>> my part.  These operator wrapping facilities are only suitable for
>> wrapping operators which work on rvalue arguments.   If you want to
>> wrap your operators which work on non-const lvalues, you should write
>> something more like:
>>        FXStream& (FXStream::*pmf)(FXchar&) = &FXStream::operator<<;
>>        ...
>>           .def('__lshift__', pmf, return_self());
> Ok, maybe if I explain what FXStream is: FXStream is like an 
> iostream

I think I figured that out.

> , or most accurately like QDataStream in Qt. You read and 
> write variables from and to whatever backs it.
> Therefore usage would be as follows:
> FXStream s;
> s << 5;
> int foo;
> s >> foo;
> etc.
> Can boost.python wrap this sort of usage?

I just fixed it so that it can.  However, you may have trouble with
the return type of your operator<<, if it's a reference.  There's no
provision for using call policies with operators.

>> FWIW, Wrapping all these different operators for lots of different
>> integer types is probably a waste of time because Python only has one
>> int type.  Wrapping overloads on int and ushort, for example, is
>> redundant.
> Mmm. This is a problem I was going to tackle eventually. I can't use 
> python's pickle for various reasons so I have to really interface 
> python directly with this. And I most certainly need to write short 
> ints for example.

You'd better pick a different interface, then, 'cause Python doesn't
give you short ints.

Dave Abrahams
Boost Consulting

More information about the Cplusplus-sig mailing list