Domanda

Please excuse me if my terminology is wrong.

Is it possible to determine the value of a type argument in class template instance in D programming language?

Please consider following classes structure:

class Entity {
}

class User : Entity {
}

class Collection(E:Entity) {
}

class UsersCollection : Collection!(User) {
}

Now, having access to "UsersCollection" I can determine that it is a subclass of Collection but I want to determine what type of entity is it a collection of ("User")

Here are my experiments:

import std.traits;

int main(){

        pragma(msg, BaseTypeTuple!UsersCollection);
        pragma(msg, TransitiveBaseTypeTuple!UsersCollection);
        pragma(msg, BaseClassesTuple!UsersCollection);
        //outputs:
        //(in Collection!(User))
        //(Collection!(User), Object)
        //(Collection!(User), Object)

        pragma(msg, UsersCollection);
        pragma(msg, isInstanceOf!(Collection, UsersCollection));
        //outputs:
        //UsersCollection
        //false

        foreach(BC; BaseClassesTuple!UsersCollection){
            pragma(msg, BC);
            pragma(msg, isInstanceOf!(Collection, BC));
        }
        //outputs:
        //Collection!(User)
        //true
        //Object
        //false

        return 0;
}

As you see the first element of BaseClassesTuple!UsersCollection is "Collection!(User)" but how to get the "User" out of it?

È stato utile?

Soluzione

You'll want to use the is expression for this http://dlang.org/expression.html#IsExpression (form #7 in the docs):

    static if(is(BaseClassesTuple!UsersCollection[0] == Collection!Type, Type)) {
            // this is an instance of Collection
            // with the argument passed as Type
            pragma(msg, "MATCH!");
            pragma(msg, Type);
    }

We check the base class and see if its type equal to a particular declaration. The way that works is you basically write out the type declaration with placeholders, then do a comma separated list of the placeholders you used.

So "Collection!Type, Type" matches anything that would have been instantiated as Collection, with Type being the argument.

Then, inside the static if, those placeholders are available as aliases to the arguments. So when we use Type inside that static if, it tells you what the arg is. Here, we got out Type.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top