foreach on a tuple using aliases
Alex
sascha.orlov at gmail.com
Sun Aug 5 14:48:55 UTC 2018
On Sunday, 5 August 2018 at 14:07:30 UTC, 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? Is it too difficult to fix?
>
> 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
Another workaround would be
´´´
void main()
{
Foo foo;
assert(isFoo!foo);
static struct X { int i; Foo foo; }
X x;
static foreach(i, item; typeof(x).tupleof)
static if(is(typeof(item) == Foo)) // line A
static assert(isFoo!item); // line B
else
static assert(!isFoo!item);
}
´´´
wouldn't it?
More information about the Digitalmars-d-learn
mailing list