Semantics of specialization, constraints, and conditional compilation

Ali Çehreli acehreli at yahoo.com
Thu May 20 23:45:11 PDT 2010


Mostly babbling... Please comment here and there... :)

What are the semantics of the three? What are your guidelines when 
choosing among them? Is my understanding below correct? Have I missed 
other related D features?


- specialization means "there is a general definition somewhere; but 
this one is special for the matching conditions in the template 
parameter list"

That is an easy concept, but the syntax can be very confusing. The 
following example is from the spec at 
http://digitalmars.com/d/2.0/template.html

template TFoo(T : T[])  { ... }

(I think we discussed this syntax a short time ago.)

The only way that I could wrap my head around that was from 
right-to-left, and I am still not sure whether this is correct: "If the 
parameter fits T[] (i.e. if the parameter is an array), then set T to be 
the type of the array element."

Reading it left-to-right doesn't work: "when T matches T[]", which would 
be impossible, because no type matches the array of that type.


- constraints mean "Consider this definition only if the conditions in 
the constraints are true"

This is not that hard either, but there is a problem with constraints. 
When two definitions of a template given, and when one of them has a 
constraint, the use that matches the constraints also matches the 
definition without the constraint:

void foo(T)()
{}

void foo(T)()
     if (T.sizeof == 4)
{}

void main()
{
     foo!int();   // <-- compiler error
}

Error: template instance foo!(int) matches more than one template 
declaration, foo(T) and foo(T) if (T.sizeof == 4)

It means that we must have exclusion on the other template:

void foo(T)()
     if (T.sizeof != 4)     // <-- reverse logic
{}

void foo(T)()
     if (T.sizeof == 4)     // <-- special
{}

Perhaps this proves that constraints are not suitable for specialization.


- conditional programming (static if) means "Include this block of code 
conditionally"

We could use this feature to conditionally include as many lines as we 
want within the body of the template:

void foo(T)()
{
     static if (T.sizeof == 4) {
         // ... special ...

     } else {
         // ... general ...
     }
}

The 'is exression' at 
http://digitalmars.com/d/2.0/expression.html#IsExpression can be very hairy:

   alias long[char[]] AA;

   static if (is(AA T : T[U], U : const char[]))
   {
     writefln(typeid(T));	// long
     writefln(typeid(U));	// const char[]
   }

That is magic! :) Perhaps I should read it from right to left:

   if U matches const char[]
   if AA matches T[const char[]]
   then T is the type of the array element
   and AA is... ??? brain ache! :)
   ... trying again ...
   AA is T... But wait! T was something else
   Fail! :/

Additionally, there is __traits. The spec at 
http://digitalmars.com/d/2.0/traits.html says:

<quote>
This is useful for:

     * Giving better error messages inside generic code than the 
sometimes hard to follow compiler ones.
     * Doing a finer grained specialization than template partial 
specialization allows for.
</quote>

Does it mean "when used with static if?".

Thank you,
Ali


More information about the Digitalmars-d-learn mailing list