Here is an example from the tutorial: struct Point(T) { T x; T y; }
T getResponse(T)(string question) { writef("%s (%s): ", question, T.stringof); T response; readf(" %s", &response); return response; } Point!T getResponse(T: Point!T)(string question) { writefln("%s (Point!%s)", question, T.stringof); auto x = getResponse!T(" x"); auto y = getResponse!T(" y"); return Point!T(x, y); } void main() { auto pt = getResponse!(Point!int)("point"); } I don't understand how to read this signature: Point!T getResponse(T: Point!T)(string question). Clearly it's not supposed to be saying that T is subclass of Point!T, so those Ts must refer to different types. But when I rename it to getResponse(U: Point!T) I get a compilation error (unknown identifier T). Another question: say I have a template class Pair: class Pair(A, B) { A a; B b; this(A a, B b) {this.a = a; this.b = b;} } How to write a specialization for getResponse matching Pair!(A, B) with any type arguments A and B? I tried this: T getResponse(T)(string question) if (is(T: Pair!(A, B), A, B)) { auto a = getResponse!A(" a"); auto b = getResponse!B(" b"); return new Pair!(A, B)(a, b); } but get a compile error: error: d.getResponse called with argument types (string) matches both: d.d(19): getResponse(T)(string question) and: d.d(40): getResponse(T)(string question) if (is(T : Pair!(A, B), A, B))