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