Ref local variables?

Ben Davis entheh at cantab.net
Sun Jan 8 12:28:24 PST 2012


I also meant to say: 80x25? Epic :D

On 08/01/2012 20:25, Ben Davis wrote:
> 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