digitalmars.D.learn - Is using function() in templates possible at all?
- Sjoerd Nijboer (34/34) Apr 11 2018 I am trying to do a binary insert into my sorted array.
- Alex (30/31) Apr 11 2018 I would say, alias template parameter is your friend.
- Sjoerd Nijboer (8/11) Apr 11 2018 It works, thank you!
- Nicholas Wilson (7/16) Apr 11 2018 There is, with template constraints:
- Laurent =?UTF-8?B?VHLDqWd1aWVy?= (13/19) Apr 12 2018 If the function is declared with explicit parameter types:
- Alex (24/25) Apr 12 2018 There are cool things possible, if the param type is explicitly
- Laurent =?UTF-8?B?VHLDqWd1aWVy?= (2/27) Apr 12 2018 Getting rid of redundancy. Now that's nice !
I am trying to do a binary insert into my sorted array. To sort classes and structs I would like to give a delegate `(t) => t.myValue` to sort on that value whitout having to implement an interface or specifically declare opCmp for every class I want to have sorted. After all, I might want one group of objects of a given class sorted in one way and another group of objects sorted on another way depending on the usecase. expression to sort such list after insertion, and is also usefull in other circumstances. But is it possible in D to do something simular but then pass on this Function() during compile time? something like ` void main() { SortedList!(Vector3, (v) => v.y) list; } struct Vector3 { float x, y, z; } class SortedList(T, int function(T) comparer) { T[] array; int foo(T t) { for(int i = 0; i < array.lenght; i++) { if(comparer(this.otherT) <= comparer(t)) { //do stuff array[i] = t; } } } } `
Apr 11 2018
On Wednesday, 11 April 2018 at 21:07:03 UTC, Sjoerd Nijboer wrote:class SortedList(T, int function(T) comparer)I would say, alias template parameter is your friend. https://dlang.org/spec/template.html#TemplateAliasParameter ´´´ import std.stdio; import std.range; void main() { auto list = new SortedList!(Vector3, v => v.y)(); assert(list.array.empty); list.foo(Vector3.init); } struct Vector3 { float x, y, z; } class SortedList(T, alias comparer) { T[] array; auto foo(T t) { for(int i = 0; i < array.length; i++) { if(comparer(this.array[i]) <= comparer(t)) { //do stuff array[i] = t; } } } } ´´´
Apr 11 2018
On Wednesday, 11 April 2018 at 21:29:27 UTC, Alex wrote:I would say, alias template parameter is your friend. https://dlang.org/spec/template.html#TemplateAliasParameter class SortedList(T, alias comparer)It works, thank you! But just to be shure, there's no way to have this more strongly typed in D so I can enforce that `comparer`is a funciton or delegate with a specific defenition? Right now i'm relying on the template to error on some different place which might not give such a readable error message to the user.
Apr 11 2018
On Wednesday, 11 April 2018 at 22:13:33 UTC, Sjoerd Nijboer wrote:On Wednesday, 11 April 2018 at 21:29:27 UTC, Alex wrote:There is, with template constraints: class SortedList(T, alias comparer) if(is(typeof(comparer(T.init) : int)) { //... }I would say, alias template parameter is your friend. https://dlang.org/spec/template.html#TemplateAliasParameter class SortedList(T, alias comparer)It works, thank you! But just to be shure, there's no way to have this more strongly typed in D so I can enforce that `comparer`is a funciton or delegate with a specific definition?
Apr 11 2018
On Thursday, 12 April 2018 at 00:05:26 UTC, Nicholas Wilson wrote:There is, with template constraints: class SortedList(T, alias comparer) if(is(typeof(comparer(T.init) : int)) { //... }If the function is declared with explicit parameter types: ``` auto list = new SortedList!(Vector3, (Vector3 v) => v.y)(); ``` Then the template guard can even have a full type definition: ``` class SortedList(T, alias comparer) if (is(typeof(comparer) : int function(T))) { //... } ```
Apr 12 2018
On Thursday, 12 April 2018 at 11:17:01 UTC, Laurent Tréguier wrote:If the function is declared with explicit parameter types:There are cool things possible, if the param type is explicitly typed :) ´´´ import std.traits; void main() { auto list = new SortedList!((Vector3 v) => v.y)(); list.foo(Vector3.init); } struct Vector3 { float x, y, z; } class SortedList(alias comparer) if(is(ReturnType!comparer : float)) { alias T = Parameters!comparer[0]; T[] array; auto foo(T t) { // do stuff } } ´´´
Apr 12 2018
On Thursday, 12 April 2018 at 11:53:21 UTC, Alex wrote:On Thursday, 12 April 2018 at 11:17:01 UTC, Laurent Tréguier wrote:Getting rid of redundancy. Now that's nice !If the function is declared with explicit parameter types:There are cool things possible, if the param type is explicitly typed :) ´´´ import std.traits; void main() { auto list = new SortedList!((Vector3 v) => v.y)(); list.foo(Vector3.init); } struct Vector3 { float x, y, z; } class SortedList(alias comparer) if(is(ReturnType!comparer : float)) { alias T = Parameters!comparer[0]; T[] array; auto foo(T t) { // do stuff } } ´´´
Apr 12 2018