D: Unexpected output when using a delegate and EnumMembers
Artur Skawina
art.08.09 at gmail.com
Tue Jun 19 08:08:16 PDT 2012
On 06/19/12 16:44, Travis Gockel wrote:
> import std.algorithm;
> import std.stdio;
> import std.traits;
>
> enum E { a, b, c };
>
> struct S { E e; };
>
> void main()
> {
> immutable(S)[] source = [ S(E.a), S(E.a), S(E.b) ];
> foreach (e; EnumMembers!E)
> {
> size_t c = count!(x => x.e == e)(source);
> writeln(e, " -> ", c);
> }
> }
>
> I would expect the output of this program to be something along the lines of:
>
> a -> 2
> b -> 1
> c -> 0
>
> But the actual result is:
>
> a -> 2
> b -> 2
> c -> 2
>
> Curiously, changing the for loop to foreach (e; [ E.a, E.b, E.c ]) produces my
> expected output. Using foreach (e; [ EnumMembers!E ]) also produces my
> expected result, so clearly my use of the range from EnumMemebers is the
> problem here...I just don't know why.
>
> By moving the count call to a separate function:
>
> size_t counte(Range)(E e, Range src)
> {
> return count!(x => x.e == e)(src);
> }
>
> and changing c's initialization to size_t c = counte(e, source);, the program
> works as I would expect.
>
> I am clearly doing something wrong, but I have no idea what and would
> appreciate some insight.
Yes, it can be surprising, but I'm not convinced it's actually wrong
behavior (the bug is http://d.puremagic.com/issues/show_bug.cgi?id=2043)
Just do this:
size_t c = count!(function(x, e) { return x.e == e;} )(source, e);
and it will work. [1]
artur
[1] I don't do that new kinky lambda syntax, sorry. ;)
More information about the Digitalmars-d-learn
mailing list