Thread overview | |||||||||
---|---|---|---|---|---|---|---|---|---|
|
April 11, 2018 Is using function() in templates possible at all? | ||||
---|---|---|---|---|
| ||||
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. In C# this is done by passing on a lambda in for instance a LinQ 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; } } } } ` |
April 11, 2018 Re: Is using function() in templates possible at all? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sjoerd Nijboer | 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; } } } } ´´´ |
April 11, 2018 Re: Is using function() in templates possible at all? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Alex | 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.
|
April 12, 2018 Re: Is using function() in templates possible at all? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sjoerd Nijboer | 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:
>> 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?
There is, with template constraints:
class SortedList(T, alias comparer) if(is(typeof(comparer(T.init) : int))
{
//...
}
|
April 12, 2018 Re: Is using function() in templates possible at all? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nicholas Wilson | 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)))
{
//...
}
```
|
April 12, 2018 Re: Is using function() in templates possible at all? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Laurent Tréguier | 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
}
}
´´´
|
April 12, 2018 Re: Is using function() in templates possible at all? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Alex | 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:
>> 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
> }
> }
> ´´´
Getting rid of redundancy. Now that's nice !
|
Copyright © 1999-2021 by the D Language Foundation