[C++-sig] Inplace Operator Problems

David Abrahams dave at boost-consulting.com
Wed Oct 9 22:05:12 CEST 2002


"Scott A. Smith" <ssmith at magnet.fsu.edu> writes:

> Hello,
> 
> I've been trying to get inplace operators working in Boost.Python. The
> dox (sorry still on Boost 1.28.0) have the following:
> 
> 	Suppose the class BigNum has an operator+=:
> 
> 	BigNum& operator+= (BigNum const& right);
> 
> 	This can be exposed by first writing a wrapper function:
> 	BigNum& iadd (BigNum& self, const BigNum& right)
> 	{
> 	  return self += right;
> 	}
> 	and then exposing the wrapper with
> 	bignum_class.def(&iadd, "__iadd__");
> 
> This is exactly what I did with my class. Unfortunately I get the
> following problem. Take BigNum as just some integer like class. In
> Python if I do
> 
>       X = BigNum(1)
>       Y = X 
>       Y += BigNum(3)
> 
> Then both X and Y are set to 4. Somehow X and Y point to the same
> thing when going into the += wrapped function and it does not
> acknowledge that Y should change without X. I guess such referencing
> is done automatically in Python, but in a normal addition it figures
> out that just fine (i.e. using op_add). Is it obvious to others what I
> am doing wrong?

You'll see the same behavior if you do this with classes in Pure
Python. The way around it is to do this:

 	BigNum iadd (BigNum& self, const BigNum& right)
 	{
 	  return BigNum(self) += right;
 	}

In Python Y += Z rebinds Y to the result of calling __iadd__(Y,Z). If
you return the same object that was passed in from __iadd__, and
essentially modify the object in-place, you get the equivalent of no
rebinding.

Hmm, it might be neccessary to extend Boost.Python v2 to better handle
cases like this...

-- 
           David Abrahams * Boost Consulting
dave at boost-consulting.com * http://www.boost-consulting.com





More information about the Cplusplus-sig mailing list