ref tuples

Brad Anderson eco at gnuk.net
Wed Jul 3 10:10:22 PDT 2013


On Wednesday, 3 July 2013 at 16:35:18 UTC, Artur Skawina wrote:
> On 07/03/13 18:29, Brad Anderson wrote:
>> On Wednesday, 3 July 2013 at 11:54:39 UTC, Artur Skawina wrote:
>>> On 07/03/13 02:22, Brad Anderson wrote:
>>>> C++11's std::tuple includes a function std::tie that takes 
>>>> references to the arguments and returns a tuple that 
>>>> maintains the references to the arguments.
>>>>
>>>> Along with the usual cases where you'd want reference 
>>>> semantics it also enables this interesting construct for 
>>>> unpacking tuples.
>>>>
>>>> int a, b;
>>>> tie(a, b) = make_tuple(1, 2);
>>>>
>>>> assert(a == 1 && b == 2);
>>>>
>>>> Is there any way to do something similar with 
>>>> std.typecons.Tuple?
>>>
>>> Well, aliases can be used to get a similar effect.
>>>
>>>    template tie(A...) { alias tie = A; }
>>>    tie!(a, b) = tuple(1, 2);
>> 
>> That won't work.  a and b aren't held as references (also you 
>> passed them as type parameters :P).
>
> Try it...
>
> And, yes, the fact that 'A...' template parms accept symbols
> is not exactly obvious. But it's much more useful that way.
>
> artur

Huh, I had no idea you could do something like that. I stand 
corrected. Thanks.

That does get tie = working but doesn't work if you want to pass 
it around which is actually more at the heart of what I'm 
interested in.

To get straight to the point, I was playing around with 
implementing bearophile's enumerate() feature request (something 
I've wanted myself).  Both his posted solution [1] and my own 
quick testing hack (auto enumerate(Range)(Range r) { return 
zip(sequence!"n"(), r); }) lose the ability to do ref elements in 
foreach that can modify the source range:

---
auto a = ["a", "b", "c"];
foreach(i, ref item; a.enumerate())
   item = to!string(i);

assert(a == ["0", "1", "2"]); // fails, a is still ["a", "b", "c"]
---

They don't work because both the tuples he returns from front and 
the tuples zip creates aren't references to the originals so you 
are just changing the copy stored in the tuple.

Something like "alias RefIntTuple = Tuple!(ref int, ref int);" 
gives a compiler error (Error: expression expected, not 'ref').

1. http://d.puremagic.com/issues/show_bug.cgi?id=5550#c2


More information about the Digitalmars-d-learn mailing list