Joshua:
oh wow didnt know u could do that. much nicer.

It's an is() expression (you cited my tutorial, there is an appendix on it). It recently became even more powerful, so the tutorial is not accurate any more.

A few months ago, you couldn't do 

is(Type _ == Template!Args, Args...)

with Args being whatever number of args are needed. Only fixed numbers were possible:

is(Type _ == Template!(T), T)
is(Type _ == Template!(T,U), T,U)
and so on...

Now, testing for a Tuple is easy:

is(Type _ == Tuple!Args, Args...)



What's even nicer with an is() expr is that the introspection info is accessible when used inside a static if. So with Artur's code, CT can be seen inside the true branch of the static if.

template ComplexType(T) 
if (isComplex!T) // Using the previously defined isComplex
{
    // we know it's a Complex!CT, for some CT
    static if (is(T _ == Complex!CT, CT)
        alias CT ComplexType;
    else
        static assert(false, "This should not happen!");
}

void main()
{
    Complex!double c;
    writeln(ComplexType!(typeof(c)).stringof);
}