[C++-sig] Suppressing assignment operator in Boost.Python

Abhi abhi at qualcomm.com
Fri Apr 21 16:36:01 CEST 2006



--On Friday, April 21, 2006 2:07 PM +0300 Roman Yakovenko 
<roman.yakovenko at gmail.com> wrote:

> On 4/21/06, Abhi <abhi at qualcomm.com> wrote:
>> namespace bp = boost::python;
>>
>>
>> BOOST_PYTHON_MODULE(Boost_YMI){
>>   bp::class_< B, boost::noncopyable>( "B" )
>>         .def( bp::init< >()[bp::default_call_policies()] )
>>        .def_readwrite("aObj", &B::aObj)
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>
> This one has been fixed and unit test has been added.
> Now pyplusplus will generate def_readonly.
> You will not be able to assign new object to aObj, but you will be
> able to modify
> it's state.

I want to be able to modify it in place.
Like this:
-----------------------------C++
// Example
#include <iostream>
class A
{
public:
  int x;
  A() : x(5) {}

private:
  const A& operator=(const A& a)
  {
    std::cout << "A::=" << std::endl;
    x = a.x;
    return *this;
  }
  A(const A& a);

};

class B
{
public:
  A aObj;
  B()
  {
    aObj.x = 6;
  }
};
-------------------------------
In python:

---------------.py
b = B()
a = A()

# No assignment operator for A
# so we cannot do
# b.aObj = someNewA
# but we can modify it in place
b.aObj.x  = 10;
# and also read it in place
y = b.aObj.x
--------------------

How do I generate Boost.Python bindings in py++ for doing this?
And also what does the .def look like (ie the Boost.Python binding look 
like). I could just do the code.wrapper in py++ for it.

thanks
- Abhi



>
> Quick work around is next:
> mb = module_builder_t( .... )
> cls_b = mb.class_( 'B' )
> cls_b.member_variable( 'aObj' ).exclude()
> cls_b.add_code( 'def_readonly( "aObj", &B::aObj )' )
>
>>     ;
>>
>>
>>     bp::class_< A, boost::noncopyable >( "A" )
>>         .def( bp::init< >()[bp::default_call_policies()] )
>>         .def_readwrite( "x", &A::x );
>> }
>>
>>
>> But this does not compile since Boost.Python generates an assignment
>> operator for the attribute aObj (which has a private assignment
>> operator).
>>
>> Is this anyway to tell Boost.Python to not generate the assignment
>> operator for aObj of B.
>
> I am not sure that I fully understand you, but proposed solution
> should work for you.
>
>> One workaround (which is not at all elegant!) is for me to write the
>> following hand-crafted methods:
>>
>> void set(B& self, A& a)
>> {
>>   self.aObj.x = a.x;
>> }
>>
>> const A& get(B& self)
>> {
>>   return self.aObj;
>> }
>>
>>  and then not expose the aObj as an attribute but rather through these
>> methods in python:
>>     bp::class_< B, boost::noncopyable>( "B" )
>>         .def( bp::init< >()[bp::default_call_policies()] )
>>         .def("set", &set)
>>         .def("get", &get, bp::return_internal_reference<>() )
>
> I don't think you need this.
>
>>
>> thanks
>> - Abhi
>
>
> --
> Roman Yakovenko
> C++ Python language binding
> http://www.language-binding.net/







More information about the Cplusplus-sig mailing list