setIntersection of struct range
Steven Schveighoffer
schveiguy at yahoo.com
Wed Aug 12 08:25:10 PDT 2009
On Tue, 11 Aug 2009 19:35:40 -0400, Jesse Phillips
<jessekphillips+d at gmail.com> wrote:
> I am trying to obtain a rang that is the intersection of two other
> ranges. To do this I am using the _setIntersection()_ function.
>
> import std.algorithm;
> import std.stdio;
>
> struct S {
> string label;
> }
>
> void main() {
> auto s1 = new S[2];
> auto s2 = new S[2];
>
> s1[0].label = "fish";
> s1[1].label = "bar";
> s2[0].label = "foo";
> s2[1].label = "fish";
>
> foreach(str; setIntersection(s1,s2))
> writeln(str);
> }
>
> The code above generates this error:
>
> C:\opt\dmd\windows\bin\..\..\src\phobos\std\functional.d(191):
> Error: static assert "Bad binary function q{a < b}.
> You need to use a valid D expression using symbols a of
> type S and b of type S."
You did not define a way to compare two S structs. Try redefining S like
this:
struct S {
string label;
int opCmp(ref const S s2) const {
if(label < s2.label)
return -1;
if(label > s2.label)
return 1;
return 0;
}
}
>
> So I attempted an intersection of string arrays, and received a
> different error. I'm not sure if I am at fault or the compiler.
> Shouldn't these work?
>
> import std.algorithm;
> import std.stdio;
> import std.array;
>
> struct S {
> string label;
> }
>
> void main() {
> auto s1 = ["fish", "bar"];
> auto s2 = ["foo", "fish"];
>
> foreach(str; setIntersection(s1,s2))
> writeln(str);
> }
>
> Which ended up with:
>
> test.d(13): Error: template std.algorithm.setIntersection(alias less
> = "a < b",Rs...)
> if (allSatisfy!(isInputRange,Rs)) does not match any function
> template declaration
> test.d(13): Error: template std.algorithm.setIntersection(alias less
> = "a < b",Rs...)
> if (allSatisfy!(isInputRange,Rs)) cannot deduce template
> function from
> argument types !()(immutable(char)[][2u],immutable(char)[][2u])
I think it's expecting dynamc arrays, not static ones. Auto is making
them static.
Try explicitly defining s1 and s2 as string[] or slice the literal, typing
them as dynamic arrays like this:
auto s1 = ["fish", "bar"][];
auto s2 = ["foo", "fish"][];
> test.d(13): Error: foreach: int is not an aggregate type
This is a dummy error because it couldn't figure out the type of
setIntersection, so it just assumes int (a quirk of dmd).
-Steve
More information about the Digitalmars-d-learn
mailing list