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