www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - sort using delegate as predicate

reply "Simon =?UTF-8?B?QsO8cmdlciI=?= <simon.buerger rwth-aachen.de> writes:
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);
}
Sep 16 2014
next sibling parent Justin Whear <justin economicmodeling.com> writes:
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);
Sep 16 2014
prev sibling parent reply "H. S. Teoh via Digitalmars-d-learn" <digitalmars-d-learn puremagic.com> writes:
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
Sep 16 2014
parent reply "Simon =?UTF-8?B?QsO8cmdlciI=?= <simon.buerger rwth-aachen.de> writes:
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.
Sep 16 2014
next sibling parent "H. S. Teoh via Digitalmars-d-learn" <digitalmars-d-learn puremagic.com> writes:
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.
Sep 16 2014
prev sibling parent Justin Whear <justin economicmodeling.com> writes:
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.
Sep 16 2014