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