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