www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - problem with custom predicate

reply "Simon =?UTF-8?B?QsO8cmdlciI=?= <simon.buerger rwth-aachen.de> writes:
I am trying to use a Container class with a custom predicate, but 
the following code does not compile. Any hints on how to do it?

import std.container;

class C
{
     int[] prio;
     RedBlackTree!(int, (a,b)=>prio[a]<prio[b]) tree;
}

I think I understand the reason why this does not work (the 
lambda cannot access the 'this' to get to 'prio'), but I can't 
think of a way to make it work. Any Ideas?
May 27 2015
parent reply drug <drug2004 bk.ru> writes:
On 27.05.2015 13:50, "Simon Bürger" <simon.buerger rwth-aachen.de>" wrote:
 I am trying to use a Container class with a custom predicate, but the
 following code does not compile. Any hints on how to do it?

 import std.container;

 class C
 {
      int[] prio;
      RedBlackTree!(int, (a,b)=>prio[a]<prio[b]) tree;
 }

 I think I understand the reason why this does not work (the lambda
 cannot access the 'this' to get to 'prio'), but I can't think of a way
 to make it work. Any Ideas?
Do you want to dynamically change priority? Why prio is outside of your predicate?
May 27 2015
parent reply "Simon =?UTF-8?B?QsO8cmdlciI=?= <simon.buerger rwth-aachen.de> writes:
On Wednesday, 27 May 2015 at 14:58:39 UTC, drug wrote:

 Do you want to dynamically change priority?
Actually yes. In my actual code I am not using a RedBlackTree but my own Container (a heap with the possibility to modify elements inside), which is notified when prio changes so it can do a (local) reordering.
 Why prio is outside of your predicate?
Well, how would I get it into the lambda? In C++ I would use a comparision class, and the constructor of the container would take an instance of that class. But D's RedBlackTree-constructor does not take such a (run-time) argument. And I dont see a way to get prio into the predicate, which is a template-argument. As I am implementing my own container anyway, I could of course do it the C++-way. But I was wondering if there is another way.
May 27 2015
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 5/27/15 9:11 AM, "Simon =?UTF-8?B?QsO8cmdlciI=?= 
<simon.buerger rwth-aachen.de>" wrote:
 On Wednesday, 27 May 2015 at 14:58:39 UTC, drug wrote:

 Do you want to dynamically change priority?
Actually yes. In my actual code I am not using a RedBlackTree but my own Container (a heap with the possibility to modify elements inside), which is notified when prio changes so it can do a (local) reordering.
It would be a very bad idea to change prio if the RBTree is constructed already (and if this works).
 Why prio is outside of your predicate?
Well, how would I get it into the lambda? In C++ I would use a comparision class, and the constructor of the container would take an instance of that class. But D's RedBlackTree-constructor does not take such a (run-time) argument. And I dont see a way to get prio into the predicate, which is a template-argument.
This is true, RedBlackTree does not take a functor as a parameter to the constructor, it just uses an alias. This should work if your RedBlackTree is scoped inside a function where the data exists. But at the time of declaration inside the class, the instance of prio doesn't exist, so you can't alias it. It would be a good enhancement I think to add support for function objects. -Steve
May 27 2015
next sibling parent reply "Meta" <jared771 gmail.com> writes:
On Wednesday, 27 May 2015 at 15:30:28 UTC, Steven Schveighoffer 
wrote:
 On 5/27/15 9:11 AM, "Simon =?UTF-8?B?QsO8cmdlciI=?= 
 <simon.buerger rwth-aachen.de>" wrote:
 On Wednesday, 27 May 2015 at 14:58:39 UTC, drug wrote:

 Do you want to dynamically change priority?
Actually yes. In my actual code I am not using a RedBlackTree but my own Container (a heap with the possibility to modify elements inside), which is notified when prio changes so it can do a (local) reordering.
It would be a very bad idea to change prio if the RBTree is constructed already (and if this works).
 Why prio is outside of your predicate?
Well, how would I get it into the lambda? In C++ I would use a comparision class, and the constructor of the container would take an instance of that class. But D's RedBlackTree-constructor does not take such a (run-time) argument. And I dont see a way to get prio into the predicate, which is a template-argument.
This is true, RedBlackTree does not take a functor as a parameter to the constructor, it just uses an alias. This should work if your RedBlackTree is scoped inside a function where the data exists. But at the time of declaration inside the class, the instance of prio doesn't exist, so you can't alias it. It would be a good enhancement I think to add support for function objects. -Steve
I thought unaryFun *does* work with all callables, including structs/classes with opCall?
May 27 2015
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 5/27/15 9:59 AM, Meta wrote:
 I thought unaryFun *does* work with all callables, including
 structs/classes with opCall?
It (binaryFun actually) declares an alias. But you need an actual instance to use in this case. You simply can't declare that in a type definition, and it won't be set up properly in the constructor even if you could. You need an instance in order to use an alias to that instance. What likely would happen is if the functor is a callable type, and that type is not a functor itself (i.e. doesn't define static opCall), is that RedBlackTree would then require an instance of that type as part of the constructor. -Steve
May 27 2015
parent "Meta" <jared771 gmail.com> writes:
On Wednesday, 27 May 2015 at 17:56:27 UTC, Steven Schveighoffer 
wrote:
 On 5/27/15 9:59 AM, Meta wrote:
 I thought unaryFun *does* work with all callables, including
 structs/classes with opCall?
It (binaryFun actually) declares an alias. But you need an actual instance to use in this case. You simply can't declare that in a type definition, and it won't be set up properly in the constructor even if you could. You need an instance in order to use an alias to that instance. What likely would happen is if the functor is a callable type, and that type is not a functor itself (i.e. doesn't define static opCall), is that RedBlackTree would then require an instance of that type as part of the constructor. -Steve
Yes, sorry, I meant binaryFun. I remember having a similar problem with tee, and decided to just disallow passing in the name of a struct/class with opCall as a template argument, and instead require that an instance is passed at runtime.
May 27 2015
prev sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
On 05/27/2015 05:30 PM, Steven Schveighoffer wrote:
 On 5/27/15 9:11 AM, "Simon =?UTF-8?B?QsO8cmdlciI=?=
 <simon.buerger rwth-aachen.de>" wrote:
 On Wednesday, 27 May 2015 at 14:58:39 UTC, drug wrote:

 Do you want to dynamically change priority?
Actually yes. In my actual code I am not using a RedBlackTree but my own Container (a heap with the possibility to modify elements inside), which is notified when prio changes so it can do a (local) reordering.
It would be a very bad idea to change prio if the RBTree is constructed already (and if this works).
 Why prio is outside of your predicate?
Well, how would I get it into the lambda? In C++ I would use a comparision class, and the constructor of the container would take an instance of that class. But D's RedBlackTree-constructor does not take such a (run-time) argument. And I dont see a way to get prio into the predicate, which is a template-argument.
This is true, RedBlackTree does not take a functor as a parameter to the constructor, it just uses an alias. This should work if your RedBlackTree is scoped inside a function where the data exists. But at the time of declaration inside the class, the instance of prio doesn't exist, so you can't alias it. It would be a good enhancement I think to add support for function objects. -Steve
Also, apart from missing implementation, there is no good reason why the code given should not work, is there? I think nested template instantiation should work in all scopes. (Of course, there is the issue that nested structs are somewhat arbitrarily not given a context pointer when declared within a class/struct, so this might be a little inconsistent in case it also works for structs, no question for classes though: just instantiate as nested class.)
May 27 2015