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