Thread overview
foreach doesn't work when accessing elements as supertypes
Aug 10, 2005
xs0
Aug 10, 2005
BCS
Aug 10, 2005
xs0
Aug 13, 2005
Thomas Kühne
August 10, 2005
import std.stdio;

class Foo
{
}

class Bar : Foo
{
}

void fails()
{
	Bar[] bars=new Bar[100];
	foreach(Foo f; bars)
		writefln("Should work as well");
}

void succeeds()
{
	Bar[] bars=new Bar[100];
	Foo[] foos=bars;
	foreach(Foo f; foos)
		writefln("Works");
}

-----

> dmd test.d
test.d(14): foreach: Bar [] is not an array of test.Foo

-----

This seems inconsistent to me. I can see why using

foreach(inout Foo f; bars) {}

would fail - writing a Foo into Bar[] is a bad idea, but the form above should work, or, alternatively, foos=bars should also fail (I prefer that it works, though, if it matters :). As it is now, it just doesn't make much sense, at least to me..

DMD 0.129 on WinXP


xs0
August 10, 2005
I agree, your code should be legal and work just fine.
However if you need something now, this quick workaround compiles:


import std.stdio;

class Foo
{
}

class Bar : Foo
{
}

void fails()
{
Bar[] bars=new Bar[100];

// cast bars to Foo ===========

foreach(Foo f; cast(Foo[])bars)
writefln("Should work as well");
}

void succeeds()
{
Bar[] bars=new Bar[100];
Foo[] foos=bars;
foreach(Foo f; foos)
writefln("Works");
}


In article <dddlpj$q05$1@digitaldaemon.com>, xs0 says...
>
>This seems inconsistent to me. I can see why using
>
>foreach(inout Foo f; bars) {}
>
>would fail - writing a Foo into Bar[] is a bad idea, but the form above should work, or, alternatively, foos=bars should also fail (I prefer that it works, though, if it matters :). As it is now, it just doesn't make much sense, at least to me..
>
>DMD 0.129 on WinXP
>
>
>xs0


August 10, 2005
BCS wrote:
> I agree, your code should be legal and work just fine.
> However if you need something now, this quick workaround compiles:

Well, an even easier workaround is

foreach(Bar f; bars) ...

:)

The things was that I changed some array to something more specific, and all the places where it was being read needed to be updated, which I think was quite needless... even more so, because you can implicitly cast the array anyway, just not in foreach..


xs0


> void fails()
> {
> Bar[] bars=new Bar[100];
> 
> // cast bars to Foo ===========
> 
> foreach(Foo f; cast(Foo[])bars)
>     writefln("Should work as well");
> }
August 13, 2005
xs0 schrieb:

> import std.stdio;
> 
> class Foo
> {
> }
> 
> class Bar : Foo
> {
> }
> 
> void fails()
> {
>     Bar[] bars=new Bar[100];
>     foreach(Foo f; bars)
>         writefln("Should work as well");
> }
> 
> void succeeds()
> {
>     Bar[] bars=new Bar[100];
>     Foo[] foos=bars;
>     foreach(Foo f; foos)
>         writefln("Works");
> }
> 
> -----
> 
>> dmd test.d
> test.d(14): foreach: Bar [] is not an array of test.Foo
> 
> -----
> 
> This seems inconsistent to me. I can see why using
> 
> foreach(inout Foo f; bars) {}
> 
> would fail - writing a Foo into Bar[] is a bad idea, but the form above should work, or, alternatively, foos=bars should also fail (I prefer that it works, though, if it matters :). As it is now, it just doesn't make much sense, at least to me..
> 
> DMD 0.129 on WinXP
> 

Added to DStress as http://dstress.kuehne.cn/run/c/cast_29_A.d http://dstress.kuehne.cn/run/c/cast_29_B.d

Thomas