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