Thread overview
sort using delegate as predicate
Sep 16, 2014
Simon Bürger
Sep 16, 2014
Justin Whear
Sep 16, 2014
H. S. Teoh
Sep 16, 2014
Simon Bürger
Sep 16, 2014
H. S. Teoh
Sep 16, 2014
Justin Whear
September 16, 2014
The following code does not compile, because the custom predicate of std.algorithm.sort is a template parameter, and therefore can only be a function, but not a delegate. In C++, there is a variant of sort taking a function-object as a second (run-time) parameter, but phobos does not seems to have such a thing. It seems like a pretty common problem to me, so does anyone have a solution?



class Foo
{
  int[] order;

  bool cmp(int a, int b) const
  {
    return order[a] < order[b];
  }
}

void main()
{
  auto f = new Foo;
  int[] data;
  sort!(f.cmp)(data);
}
September 16, 2014
On Tue, 16 Sep 2014 16:19:10 +0000, Simon Bürger wrote:

> The following code does not compile, because the custom predicate of std.algorithm.sort is a template parameter, and therefore can only be a function, but not a delegate. In C++, there is a variant of sort taking a function-object as a second (run-time) parameter, but phobos does not seems to have such a thing. It seems like a pretty common problem to me, so does anyone have a solution?

Bit of a workaround, but this should do it:

   sort!((a,b) => f.cmp(a, b))(data);
September 16, 2014
On Tue, Sep 16, 2014 at 04:19:10PM +0000, via Digitalmars-d-learn wrote:
> The following code does not compile, because the custom predicate of std.algorithm.sort is a template parameter, and therefore can only be a function, but not a delegate.

What makes you think so? Template parameters certainly can be delegates. I use that all the time.


> In C++, there is a variant of sort taking a function-object as a second (run-time) parameter, but phobos does not seems to have such a thing. It seems like a pretty common problem to me, so does anyone have a solution?
> 
> 
> 
> class Foo
> {
>   int[] order;
> 
>   bool cmp(int a, int b) const
>   {
>     return order[a] < order[b];
>   }
> }
> 
> void main()
> {
>   auto f = new Foo;
>   int[] data;
>   sort!(f.cmp)(data);
> }

Try this:

	sort!(&f.cmp)(data);

In D, writing `f.cmp` (without the &) can in some contexts be misinterpreted as calling the function and passing the return value to the template parameter, which is probably why you're getting a compile error.


T

-- 
Why ask rhetorical questions? -- JC
September 16, 2014
On Tuesday, 16 September 2014 at 16:27:46 UTC, H. S. Teoh via Digitalmars-d-learn wrote:
> On Tue, Sep 16, 2014 at 04:19:10PM +0000, via Digitalmars-d-learn wrote:
>> The following code does not compile, because the custom predicate of
>> std.algorithm.sort is a template parameter, and therefore can only be
>> a function, but not a delegate.
>
> What makes you think so? Template parameters certainly can be delegates.
> I use that all the time.

Well because the delegate contains a pointer to the object, which can not be known at compile time. In fact

> sort!(&f.cmp)(data);

fails with the error "variable f cannot be read at compile time", which seems reasonable to me. On the other hand

> sort!((a,b) => f.cmp(a, b))(data);

does in fact compile, so i guess problem is solved. Thanks guys.
September 16, 2014
On Tue, Sep 16, 2014 at 04:38:04PM +0000, via Digitalmars-d-learn wrote:
> On Tuesday, 16 September 2014 at 16:27:46 UTC, H. S. Teoh via Digitalmars-d-learn wrote:
> >On Tue, Sep 16, 2014 at 04:19:10PM +0000, via Digitalmars-d-learn wrote:
> >>The following code does not compile, because the custom predicate of std.algorithm.sort is a template parameter, and therefore can only be a function, but not a delegate.
> >
> >What makes you think so? Template parameters certainly can be delegates.  I use that all the time.
> 
> Well because the delegate contains a pointer to the object, which can not be known at compile time. In fact
> 
> >sort!(&f.cmp)(data);
> 
> fails with the error "variable f cannot be read at compile time", which seems reasonable to me. On the other hand
> 
> >sort!((a,b) => f.cmp(a, b))(data);
> 
> does in fact compile, so i guess problem is solved. Thanks guys.

Mea culpa, I confused lambdas with delegates. The two are not the same thing. That will teach me to answer emails while rushing to get ready for work. :-P Sorry for the noise.


T

-- 
There is no gravity. The earth sucks.
September 16, 2014
On Tue, 16 Sep 2014 16:38:04 +0000, Simon Bürger wrote:
> 
>> sort!((a,b) => f.cmp(a, b))(data);
> 
> does in fact compile, so i guess problem is solved. Thanks guys.

Yes, this compiles because the lambda forms a closure over f.  In some respects this might even be better than the C++ as there is the possibility for inlining because the lambda literal is passed by alias.