Thread overview
Re: is expression for template structs/classes instances?
Dec 21, 2010
Jonathan M Davis
Dec 21, 2010
d coder
Dec 21, 2010
spir
December 21, 2010
On Monday 20 December 2010 20:23:49 d coder wrote:
> Greetings
> 
> I want to find if a given struct type is instantiated from a particular template struct type. For example:
> 
> struct S (T)  {
>   alias T Type;
>   T t;
> }
> 
> And later I want to find out if a given type is of type S(*)
> (basically any type instantiated from template struct S). In fact I do
> not know the type value T used at the time of instantiating S!(T).
> 
> I was looking at "is ( Type Identifier : TypeSpecialization , TemplateParameterList )" expression at http://www.digitalmars.com/d/2.0/expression.html#IsExpression . Thought there would be some way using that, but I could not find any.
> 
> Regards
> Cherry

Well, from the compiler's perspective S!int would have no relation to S!float, S!bool, or any other S!T. The template is instantiated with whatever types and values that it's given and then it's its own beast. So, really, there is no relation between the various instantiations of any particular template. I'm not sure that it would be impossible to have something in __traits or std.traits which tested whether a particular type was an instantiation of a particular template, but I'm not at all certain that it _is_ possible. Templates are used to generate code, but once generated, that code is essentially the same as it would have been had you typed it all yourself. So, my guess would be that you can't do what you're trying to do. I agree that it could be useful to be able to do it, but unfortunately, I don't think that it's possible.

If you knew enough about the type, you might be able to do some template voodoo to do it in a round-about manner, but it would be specific to the type in question. For instance, given your definiton of S, you could use _traits/std.traits to check that the type that you're testing has a member variable t. You could then check that S!(typeof(t)) was the same as the type that you were testing. So, if you get particularly cunning about it, I believe that it can be tested for in specific cases, but I don't believe that it can be done in any general way.

- Jonathan M Davis
December 21, 2010
> For instance, given your definiton of S, you could use
> _traits/std.traits to check that the type that you're testing has a member
> variable t. You could then check that S!(typeof(t)) was the same as the type
> that you were testing. So, if you get particularly cunning about it, I believe
> that it can be tested for in specific cases, but I don't believe that it can be
> done in any general way.
>

Thanks Jonathan

That is exactly what I had thought of doing. I was conscious that it
may not be the cleanest way.
Now that you are saying a cleaner way may not exist, I will go ahead
and write the code.

Regards
- Cherry
December 21, 2010
On Tue, 21 Dec 2010 09:53:49 +0530
d coder <dlang.coder@gmail.com> wrote:

> Greetings
> 
> I want to find if a given struct type is instantiated from a particular template struct type. For example:
> 
> struct S (T)  {
>   alias T Type;
>   T t;
> }
> 
> And later I want to find out if a given type is of type S(*)
> (basically any type instantiated from template struct S). In fact I do
> not know the type value T used at the time of instantiating S!(T).
> 
> I was looking at "is ( Type Identifier : TypeSpecialization , TemplateParameterList )" expression at http://www.digitalmars.com/d/2.0/expression.html#IsExpression . Thought there would be some way using that, but I could not find any.

I would use a flag on S, eg:

struct S(T) {
    static bool isAnS = true;
    T t;
    this (T t) {this.t = t;}
}
void main () {
    auto i = S!(int)(3);
    if (i.isAnS)
        writeln("i is an S");
}

If you were dealing with classes, you could use an interface (or fake super-class):

interface I {}
class C(T) : I {
    T t;
    this (T t) {this.t = t;}
}
void main () {
    auto i = new C!(int)(3);
    if (cast(I)i)
        writeln("i is a C");
}

[Note: In my opinion, that's precisely what interfaces are for.]
Both solutions have the nice advantage of letting down hairy is() expressions ;-)

Denis
-- -- -- -- -- -- --
vit esse estrany ☣

spir.wikidot.com