[C++-sig] Re: Boost.Python << & >> bug
Niall Douglas
s_sourceforge at nedprod.com
Tue Aug 5 00:54:18 CEST 2003
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.
> > 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.
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 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.
> 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, 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?
> 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.
Personally I'd envisage an ideal wrap as exposing as much as possible
of the underlying interface. You'd almost certainly never use 85% of
it as at a python level you'd keep pretty high-level. But
occasionally you would need to get down & dirty, especially if for
example the end-user didn't have access to the source.
Cheers,
Niall
More information about the Cplusplus-sig
mailing list