Ref local variables?

Ben Davis entheh at cantab.net
Sun Jan 8 12:25:57 PST 2012


There are two things going on in your example:

1. Use of 'auto' where I'm currently having to write 'MapTile*' and 
wanted to write 'ref MapTile'. It will infer 'MapTile*'. Or, if you 
forget the &, then it will infer 'MapTile' and do the copy that I want 
to avoid. So it might be slightly more error-prone this way.

2. Use of a template function, allowing f() to take any type, not just 
MapTile. Interestingly you're passing MapTile*, AND the parameter is 
ref, so f() could change the pointer itself for the caller if it wanted 
to! Also, if you called f() elsewhere with just a MapTile, you'd have 
two copies if the function kicking around. So it saves us having to 
write the *, but at the expense of some messiness. (Also prevents a lot 
of the compile-time checks for f() from happening until f() is used.)

At least that's assuming D templates are like C++ ones. I haven't read 
up on D templates yet. :)

So unfortunately, neither solution really solves the problem.

I suspect 'ref' for local variables could be added, and hasn't because 
it didn't figure in the specific use cases that someone had in mind when 
implementing it for parameters and 'foreach' variables. But it's also 
possible that (unlike in Java) local variables can do stuff that 
parameters can't (which I don't know about), which makes it impossible 
to allow 'ref' ones without invalidating a compile-time check or 
something. Hence why I was asking. :)

Anyway, I hope I've been able to help a bit with your own D adventure :)

Ben :)

On 08/01/2012 19:27, simendsjo wrote:
> I got something working, but only when using templates. Take the
> following with a grain of salt as I'm a newbie myself.
>
> struct MapTile {
> string id;
> }
>
> enum w = 80, h = 25;
> MapTile[w*h] map;
>
> ref MapTile getTile(int x, int y) {
> return map[y*w+x];
> }
>
> void f(T)(ref T tile) {
> tile.id = "f()";
> }
>
> void g(ref MapTile tile) {
> tile.id = "g()";
> }
>
> void main() {
> // You can use auto ref return to set values directly
> getTile(10,10).id = "a";
> assert(getTile(10,10).id == "a");
>
> // And using templated ref arguments, you can pass by reference
> // note that I need to take the reference even when
> // using auto ref return
> auto tile = &getTile(1,1);
> f(tile);
> assert(tile.id == "f()");
>
> // But you'll need a dereference if not using a template
> g(*tile);
> assert(tile.id == "g()");
>
> assert(getTile(1,1).id == "g()");
> }
>



More information about the Digitalmars-d-learn mailing list