Best Way to Pass Template Typed Alias Parameters for Functions?

Vijay Nayar madric at gmail.com
Sun Dec 23 19:19:31 UTC 2018


On Sunday, 23 December 2018 at 19:10:06 UTC, Alex wrote:
> 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...

You are correct again! Playing around with using classes and 
functions returning the wrong type or not having a const 
argument, it seems that the compiler will assure that all the 
conditions needed by the wrapper function are satisfied and give 
a clear error.

I don't know when this happened, but this definitely makes the 
language a lot easier to use for these circumstances, and all the 
std.traits stuff in "static this()" can be thrown out.


More information about the Digitalmars-d-learn mailing list