Curious effect with traits, meta, and a foreach loop ... mystifies me.

Adam D Ruppe destructionator at gmail.com
Tue Sep 7 17:33:31 UTC 2021


On Tuesday, 7 September 2021 at 17:24:34 UTC, james.p.leblanc 
wrote:
>    // this fails with: "Error: variable 'i' cannot be read at 
> compile time
>    //
>    // foreach( i ; 0 .. 3 ){
>    //    ptr = u.tupleof[i].x.ptr;

tuples only exist at compile time, so you'd have to make sure the 
indexing is itself compile time. Consider that unlike an array, 
each index might give a different type, so like what would

struct A { int a; string b; }

A a;
int idx;
some_type c = a.tupleof[idx];


Which type is some_type? Is it int or string? Impossible to tell 
since it doesn't know what idx is. So idx needs to be known at 
compile time so it knows which type you get there.

The reason why it works here:

foreach( i, val ; u.tupleof ){


is because the compiler knows you're specifically looping over 
the tupleof, so it expands it and knows what i is going to be at 
compile time. If you assigned that i to an intermediate variable 
then it would break this direct knowledge and it doesn't compile 
again.


If you want to do a runtime lookup, you need to separate the two 
pieces. This pattern works:


switch(runtime_index) {
    foreach(i, val; item.tupleof)
      case i:
            // use val
}


So the switch is at runtime but the loop and cases are all known 
at compile time.


More information about the Digitalmars-d-learn mailing list