C++ reference type

David Medlock noone at nowhere.com
Sat Jun 24 20:00:46 PDT 2006


Tom S wrote:

> David Medlock wrote:
> 
>> Tom S wrote:
>>
>>> David Medlock wrote:
>>>
>>>> The attribute functions in classes serve this purpose do they not?
>>>>
>>>> C++:
>>>> int& my_attr();
>>>>
>>>> D:
>>>> void my_attr( int );
>>>>
>>>> use, in both cases:
>>>> foo.my_attr = 100;
>>>
>>>
>>>
>>> Unless you want to be able to say 'foo.my_attr++;'
>>> or 'foo.someStruct.bar = 1;'
>>>
>>> The latter can be accomplished by making the function return a 
>>> pointer to the struct, but then you cant say 'Foo x = my_attr();'
>>>
>>>
>> Ok, but what exactly does that buy you?
>>
>> If you want reference semantics use a class.
>> If you want opPostInc use a struct.
>>

This should have read 'value semantics' not opPostInc.

<snip>
> Excuse me, but I have no idea what you're talking about. 

I am talking about 'possible' versus 'thats how we do it in C++'.

If you want to use C++ idioms, then yes its very hard to use D that way.
The point was that its (somewhat of) a shortcoming.

Certain C++ idioms require new ones in D. Thats not 'worse', its just 
different.

> Reference 
> return types are useful in many cases.
 > E.g. if you want to implement
> your own Array class. With normal arrays you can say:
> 
> int[] arr1; ... ; arr1[0] += 2;
> 
> but when you define your own array, like:
> 
> Array!(int) arr2; ... ;
> 
> then how do you implement 'arr2[0] += 2;' ?
> 
> You can't, because there are only opIndex and opIndexAssign operators. 
> There's no opIndexAddAssign and opIndex*Assign for that purpose :0

   You can't opAddAssign in that case yes, but you can add 2 to the 
first item with:

   arr2[0] = arr2[0] + 2;

Is this really a lot worse?  Its maybe 2-3 cycles at the most?

> This gets worse, e.g. if you have a
> 
> struct Foo {
>     int bar;
> }
> 
> Foo[] arr3; ... ; arr3[0].bar = 1;
> 
> but when you define
> 
> Array!(Foo) arr4; ... ;
> 
> then to accomplish the 'arr4[0].bar = 1;' functionality, you have to 
> make opIndex return a pointer. Yet then you can't say 'Foo x = arr4[0];' 
> because there's a type mismatch. You'd have to dereference the pointer.

Not to pick but you could say:

auto x = arr4[0];
x.bar = 100;

or you could simply use a different method:

class Array(T)
{
   T[]  items;
...
   T*  ptr(int n=0) { return items.ptr + n ; }
}

arr.ptr[5].bar = 1;

Since the built int arrays use a .ptr property, I usually define this 
method anyways.  Once you use it for a while its second nature.

If you need to change a lot of entries, use foreach which returns an 
inout reference.

If you want to get crazy:

   void opIndexAssign( void delegate(T* item) fn, int n )
   {
     fn( items.ptr + n );
   }


then:
arr[0] = (Foo* f){f.bar += 3;};

hehe :P

Seriously though, if the item is small enough to not warrant a class, 
then just extend the container class and define a custom method to 
update the item.

-DavidM




More information about the Digitalmars-d mailing list