Determine if a type if derived from a template parameter

Simen Kjærås simen.kjaras at gmail.com
Thu Apr 11 11:45:44 UTC 2019


On Thursday, 11 April 2019 at 10:49:38 UTC, Alex wrote:
> On Thursday, 11 April 2019 at 08:57:10 UTC, Basile B. wrote:
>> On Wednesday, 10 April 2019 at 19:28:38 UTC, Alex wrote:
>>> e.g.,
>>>
>>> class X(T,S)
>>> {
>>>    T x;
>>>    S y;
>>> }
>>>
>>> Somehow determine if x's type is derived from the template 
>>> parameter.
>>>
>>> I doubt D has this capability but it would be nice for 
>>> certain things. In my reflect library the types must be 
>>> specified such as Reflect!(X!(int,float)) and ideally I would 
>>> like to do Reflect!(X!(T,S)) to get generic reflection 
>>> information. This helps reduce overhead as one could reflect 
>>> once on the generic type, cache the results, then simply 
>>> modify the results for specifics.
>>
>> You can detect a match between a member and a template 
>> argument but you cant know if the match is a coincidence or on 
>> purpose. For example:
>>
>>   class X(T)
>>   {
>>       T x;
>>       int y;
>>   }
>>
>>   alias X1 = X!int;
>>
>> here X1.y matches to T but it's a coincidence.
>> The problem that you'll be faced to is that the template 
>> parameters are replaced by the symbol or the type.
>
> Yes, which is my point, so one isn't detecting anything. It 
> would be very error prone to assume if a type is the same as 
> the type of the parameter then it is that parameter.
>
> This is why I asked if there was a way to do this. The compiler 
> easily knows this information since it has to do the 
> replacement. The only way to hack it is to read the source 
> unless there is some way way in D.

There is no way to check this in D today. It's also impossible in 
the general case, since the relationship between a field and a 
template parameter can be arbitrarily complex:

template RandomType(T) {
     static if (__DATE__[0] == 'A')
         alias RandomType = int;
     else
         alias RandomType = T;
}

struct S(T) {
     RandomType!T a;
}

// Should print "T" unless __DATE__ starts with an A.
// Or should it really?
pragma(msg, __traits(getTemplateParameterName, S!string.a));

For this very same reason, it's also impossible to get a generic 
S where you can simply replace T with the type you want to.

Simply put, D's templates are much more powerful than the 
generics found in Java and C#, and this power comes with some 
cost.

--
   Simen


More information about the Digitalmars-d mailing list