C++ reference type

Tom S h3r3tic at remove.mat.uni.torun.pl
Sun Jun 25 02:01:51 PDT 2006


David Medlock wrote:
> Tom S wrote:
>> David Medlock wrote:
>>> If you want reference semantics use a class.
>>> If you want opPostInc use a struct.
>>>
> 
> This should have read 'value semantics' not opPostInc.

Heh... now it makes more sense ;)



> <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.

If it requires you to create workarounds all over the place, makes code 
less transparent than the C++ way and is less efficient, then I'm 
tempted to say that it's worse.



>   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?

It's not about speed in *this* case. The compiler might optimize it 
away. The point is that if you use normal arrays in some place, but then 
decide to switch to your custom classes, you may be in trouble. Say you 
have some myArray which stores structs and somewhere you write:

myArray[i].prop = 5;

The code previously used a builtin array and was just fine. After 
changing to the custom array template, it doesnt work as expected. It 
changes the 'prop' in a temporary object. Ok, you then realize what is 
up and modify the opIndex to return a pointer. But then all of a sudden 
code like this:

MyStruct foo = myArray[i];

stops working because myArray[i] returns a pointer and there's a 
mismatch. Ok, you fix all of these lines to MyStruct foo = *myArray[i];

You live happily, until one day you find out that your custom logging 
functions are behaving in a weird way. Instead of printing the contents 
of your MyStruct's, they output some ridiculous hexadecimal numbers. You 
jump into the code just to find out (after some struggles), that the 
wrong logging function was called, because you have

void log(MyStruct);
and
void log(void*);

and somewhere in your code you had log(myArray[i]). No error was 
reported because the compiler silently assumed that you wanted to print 
a pointer.



>> 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;

You could with classes, but in this case typeof(arr4[0]) is a struct.



> 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.

Yet I don't feel like losing array bounds checking... It would have to 
be 'arr.ptr(5).bar = 1;' plus a modification to the 'ptr' function. But 
then it doesn't read as 'arr[5].bar = 1;'.

At the moment the language doesn't provide enough abstraction in this 
area. At least IMO.



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

Sure.



> 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

Ummm... no, thanks :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.

That's a corner case which misses the point a bit...



-- 
Tomasz Stachowiak  /+ a.k.a. h3r3tic +/



More information about the Digitalmars-d mailing list