[C++-sig] Re: contained structure access

David Abrahams dave at boost-consulting.com
Fri Nov 8 02:27:39 CET 2002


Graeme Lufkin <gwl at u.washington.edu> writes:

>>So, did you look at this line?
>>
>>>
>>/net/mondo-1/nbody/gwl/projects/boost_1_29_0/boost/python/object/make_instance.hpp:22:
>>> `sizeof' applied to incomplete type
>>> `boost::STATIC_ASSERTION_FAILURE<false>'
>>
>>The source line is:
>>
>>        BOOST_STATIC_ASSERT(is_class<T>::value);
>>
>>Which means you can only return a reference to an object of class
>>type. Since double is not of class type, it complains.
>>
>>Why don't you use return_value_policy<copy_non_const_reference>
>>instead?
> 	Aha! I have (sort of) seen the light.  I think I'm beginning to
> understand these return_value_policy<> things.  So I want my function to
> return a reference to a built-in type.

You're asking it do do that by using return_internal_reference<>. I
can't comment on what you want.

> But I want the actual object, not a copy, so that I can assign it to
> something.   So I want reference_existing_object.  However, this also
> only works on objects (same error as before).  

But __getitem__ will never be called for x[y] = z in Python. You need
__setitem__ for that. Python is not like C++; there are no references.
I've said it before, and I'll say it again:

    You can learn a lot by experimenting in pure Python.

You can also RTF(Python)M to find these things out.

> I tried using copy_non_const_reference, expecting that it would be
> assignable, but the change would be made to the copy, and thus not
> appear in the original object.  However, when I tried to assign like
> this 'at[0] = 3', I got: TypeError: object doesn't support item
> assignment which confuses me again.

Because you didn't define __setitem__. You can reproduce the same
error in Pure Python:

   >>> class X(object):
   ...     def __getitem__(self, y):
   ...         return 1
   >>> X()[1]
   1
   >>> X()[1] = 2
   # error

>>Just remember that when reading a property, the result is returned by
>>value unless you specify otherwise. So x.y.z = 1 becomes
>>
>>     setattr(getattr(x, "y"), "z", 1)
>>
>>If you don't do something explicit to prevent it, getattr(x, "y")
>>returns a copy of x's y member, so assigning to its z element changes
>>the wrong object.
> 	Aha again! I was not aware of the setattr() business.  My picture of
> the situation was 'x.y = 2' becomes 'set(getattr(x, "y"), 2', so I
> thought the problem would have arisen in that call to getattr(). 

Because there are no references in Python, there's no such thing as
setting anything which isn't indicated by a slice, item, or attribute.


-- 
                       David Abrahams
   dave at boost-consulting.com * http://www.boost-consulting.com
Boost support, enhancements, training, and commercial distribution





More information about the Cplusplus-sig mailing list