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. ;)