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

David Abrahams dave at boost-consulting.com
Mon Aug 4 03:41:23 CEST 2003


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

> On 3 Aug 2003 at 15:14, c++-sig at python.org wrote:
>
> Enclosed is the condensed example as requested. 

I assume you're referring to the enclosure in the other message?

> There are actually 
> two bugs but I think the first (the original) is the same as the 
> second - comment out the FXId one to see the second.

It's not clear what you want me to comment out.  Please next time
include a preprocessor directive which makes the change

        #ifdef BUG1
               ...
        #else
                ...
        #endif

> What's happening IMHO is that boost.python's wrappings of user types
> are failing to cast down to their containing types

I don't know what that means.

> so therefore the compiler gets confused. Hence the error message
> from before.

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;


> The second bug is similar (MSVC7.1 report):
>
> d:\Tornado\TClient\boost\boost\python\operators.hpp(190) : error 
> C2678: binary '<<' : no operator found which takes a left-hand 
> operand of type 'const FX::FXStream' (or there is no acceptable 
> conversion)
>         d:\Tornado\TClient\boost\boost\python\operators.hpp(190) : 
> while compiling class-template member function 'PyObject 
> *boost::python::detail::operator_l<op_lshift>::apply<L,R>::execute(con
> st L &,const R &)'
>         with
>         [
>             L=FX::FXStream,
>             
> R=boost::python::detail::unwrap_other<boost::python::other<unsigned 
> char>>::type
>         ]
>
> 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.

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());

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.

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





More information about the Cplusplus-sig mailing list