Best Way to Pass Template Typed Alias Parameters for Functions?

Alex sascha.orlov at gmail.com
Sun Dec 23 19:10:06 UTC 2018


On Sunday, 23 December 2018 at 18:53:15 UTC, Vijay Nayar wrote:
> You're right, it does compile. I'm a bit surprised. I wonder if 
> this is a relatively recent improvement in the language, 
> because last time I ran into this I had no such luck. But after 
> seeing that your example did work, I figured one could try to 
> get the best of both worlds by using a strongly-typed wrapper 
> function in one's class.  So far it seems to work:
>
> import std.traits;
>
> class A(KeyT, alias HashF) {
>   // Strongly-typed wrapper around template value parameter 
> 'HashF'.
>   static size_t hash(in KeyT key) {
>     return HashF(key);
>   }
>   static this() {
>     static assert(isCallable!HashF, "Hash function is not 
> callable!");
>     static assert(Parameters!(HashF).length == 1, "Hash 
> function must take 1 argument.");
>     static assert(is(Parameters!(HashF)[0] : const(KeyT)),
>         "Hash parameter must be const.");
>     static assert(is(typeof(HashF(KeyT.init)) : size_t),
>         "Hash function must return size_t type.");
>   }
>
>   KeyT data;
>   size_t getHash() const {
>     return hash(data);
>   }
> }
>
> void main() {
>     auto a = new A!(int, (int a) => cast(size_t) a);
>     a.data = 5;
>     a.getHash();
> }

I'm not sure, whether you need the static this() part at all, as 
all of the asserts the compiler should do even when they are 
absent...

by isCallable you restrict the HashF to not use IFTI
by calling HashF(key) you ensure implicitely, that 
Parameters!(HashF).length == 1
by having hash(in KeyT key) defined with an "in" you ensured, 
that HashF does not mutate the argument
and by defining size_t getHash() you ensured the return type of 
HashF...



More information about the Digitalmars-d-learn mailing list