New to std.algorithm and generics, no idea how to make simple things to work

John Colvin john.loughran.colvin at gmail.com
Sun Mar 9 01:06:50 PST 2014


On Friday, 7 March 2014 at 19:53:04 UTC, newguy wrote:
> I really can't wrap my head around these. I fought whole day
> trying to figure out how to do the simplest thing one can
> imagine: remove an element from a doubly linked list. Here's 
> what
> I've tried, see if there is a recurring mistake of thought or
> something:
>
> import std.stdio;
> import std.algorithm;
> import std.range;
> import std.container;
>
> struct Point {
>      int x;
>      int y;
> }
>
> void main() {
>      DList!Point points;
>      points.insert(Point(0,0));
>      points.insert(Point(10,10));
>      points.insert(Point(5,5));
>      points.insert(Point(20,20));
>
>      points.remove(takeOne(find!(p => p.x > 7)(points[])));
>      // test.d(18): Error: function
> std.container.DList!(Point).DList.remove (Range r) is not
> callable using argument types (Result)
>
>      points.linearRemove(takeOne(find!(p => p.x > 
> 7)(points[])));
>      // test.d(21): Error: template
> std.container.DList!(Point).DList.linearRemove cannot deduce
> function from argument types !()(Result), candidates are:
>      // /usr/include/dmd/phobos/std/container.d(2234):
> std.container.DList!(Point).DList.linearRemove(R)(R r) if (is(R
> == Range))
>      // /usr/include/dmd/phobos/std/container.d(2240):
> std.container.DList!(Point).DList.linearRemove(R)(R r) if (is(R
> == Range))
>      // /usr/include/dmd/phobos/std/container.d(2253):
> std.container.DList!(Point).DList.linearRemove(R)(R r) if (is(R
> == Take!Range))
>
>      points.remove(find!(p => p.x > 7)(points[]));
>      // 0
>
>      points.remove(takeOne(filter!(p => p.x > 7)(points[])));
>      // test.d(30): Error: function
> std.container.DList!(Point).DList.remove (Range r) is not
> callable using argument types (Result)
>
>      points.remove(filter!(p => p.x > 7)(points[]));
>      // test.d(33): Error: function
> std.container.DList!(Point).DList.remove (Range r) is not
> callable using argument types (FilterResult!(__lambda3, Range))
>
>      points.linearRemove(filter!(p => p.x > 7)(points[]));
>      // test.d(36): Error: template
> std.container.DList!(Point).DList.linearRemove cannot deduce
> function from argument types !()(FilterResult!(__lambda1,
> Range)), candidates are:
>      // /usr/include/dmd/phobos/std/container.d(2234):
> std.container.DList!(Point).DList.linearRemove(R)(R r) if (is(R
> == Range))
>      // /usr/include/dmd/phobos/std/container.d(2240):
> std.container.DList!(Point).DList.linearRemove(R)(R r) if (is(R
> == Range))
>      // /usr/include/dmd/phobos/std/container.d(2253):
> std.container.DList!(Point).DList.linearRemove(R)(R r) if (is(R
> == Take!Range))
>
>      foreach (Point p; points) {
>          if (p.x > 7) {
>              //points.remove(/* Somehow get the range */);
>              break;
>          }
>      }
>
>      foreach (Point p; points) {
>          writeln(p.x);
>      }
> }
>
>
> Purpose is to remove one element that matches predicate, or any
> amount really. Now DList.remove is defined as "Range 
> remove(Range
> r)" and filter is "auto filter(Range)(Range rs) if
> (isInputRange!(Unqual!Range))" with explanation "The call
> filter!(predicate)(range) returns a new range only containing
> elements x in range for which predicate(x) is true." So if I
> understand correctly, filter should return a range that I can
> remove from the list. Why isn't this working?

std.container isn't great and hasn't received enough attention. 
There are plans to improve it, but I believe we're waiting on 
std.allocator and possibly a higher level layer on top of it 
before any significant revamp is made. It is perfectly usable in 
its current state however, just not always totally pleasant.
Don't let this put you off std.algorithm and std.range, which are 
both very high quality.


More information about the Digitalmars-d-learn mailing list