foreach on a tuple using aliases
Timon Gehr
timon.gehr at gmx.ch
Sun Aug 5 15:40:13 UTC 2018
On 05.08.2018 16:07, Steven Schveighoffer wrote:
> I have found something that looks like a bug to me, but also looks like
> it could simply be a limitation of the foreach construct.
>
> Consider this code:
>
> struct Foo {}
>
> enum isFoo(alias x) = is(typeof(x) == Foo);
>
> void main()
> {
> Foo foo;
> assert(isFoo!foo);
> static struct X { int i; Foo foo; }
> X x;
> foreach(i, ref item; x.tupleof)
> static if(is(typeof(item) == Foo)) // line A
> static assert(isFoo!item); // line B
> else
> static assert(!isFoo!item);
> }
>
> Consider just the two lines A and B. If you saw those lines anywhere,
> given the isFoo definition, you would expect the assert to pass. But in
> this case, it fails.
>
> What is happening is that the first time through the loop, we are
> considering x.i. This is an int, and not a Foo, so it assigns false to
> the template isFoo!item.
>
> The second time through the loop on x.foo, the compiler decides that it
> ALREADY FIGURED OUT isFoo!item, and so it just substitutes false, even
> though the item in question is a different item.
>
> So is this a bug? Is it expected?
It's a bug. The two copies of 'item' are not supposed to be the same
symbol. (Different types -> different symbols.)
> Is it too difficult to fix?
> ...
Unlikely.
> The workaround of course is to use x.tupleof[i] when instantiating
> isFoo. But it's a bit ugly. I can also see other issues cropping up if
> you use `item` for other meta things.
>
> -Steve
More information about the Digitalmars-d-learn
mailing list