Templated delegate as template argument for structs

Simen Kjærås simen.kjaras at gmail.com
Sat Feb 20 16:32:09 UTC 2021


On Saturday, 20 February 2021 at 09:16:46 UTC, Simon van Bernem 
wrote:
> I have the following struct declaration:
>
> struct Hash_Table(Key, Value, u32 delegate(ref Key) 
> custom_hash_function = null)
[snip]
> I take it from the error that the problem is not actually the 
> delegate that I am passing, but the fact that the delegate type 
> has another template parameter as the argument type. Can 
> template arguments in D not reference previous template 
> arguments? Is there some way I can get around this?

The D way would be an alias parameter:

struct Hash_Table(Key, Value, alias custom_hash_function) {
     // ...
}

Probably also adding a constraint:

struct Hash_Table(Key, Value, alias custom_hash_function)
if (is_valid_hash_function!(Key, custom_hash_function))
{
     // ...
}

// Check if the hash function can be called with a Key
// as argument, and the result be assigned to a u32
enum is_valid_hash_function(Key, alias fn) = __traits(compiles, 
(Key k){ u32 u = fn(k); });


D lets you refer to other template parameters in the same 
template parameter list in three cases, as far as I know:

1) A type may be a subtype of an earlier parameter:

     class C {}
     struct S(TBase, TDerived : TBase) {}
     S!(Object, C) a;


2) A type parameter with a type specialization followed by 
template parameter list:

     struct Fn(U) {}
     struct S(T: Fn!Arg, Arg) {}
     S!(Fn!int) a;


3) Following a type parameter, a value parameter of that type may 
appear:

     struct S(T, T value) {}
     S!(int, 4) a;


The first two can also be combined:

     struct Fn(U) {}
     struct S(T1, T2: Fn!T3, T3 : T1) {}
     S!(int, Fn!int) a;


However, it seems 3) only works with that specific type, modulo 
storage classes. No Foo!T, no void delegate(T). At any rate, the 
alias parameter is the way it's generally done, and is more 
flexible, so just leave it at that.

--
   Simen


More information about the Digitalmars-d-learn mailing list