CommonType and non-built-in types

John Colvin john.loughran.colvin at gmail.com
Tue Oct 1 04:13:54 PDT 2013


On Tuesday, 1 October 2013 at 10:50:39 UTC, Joseph Rushton 
Wakeling wrote:
> (1) Can someone please explain to me _in detail_ the mechanics 
> of the code which identifies whether the first 2 template 
> arguments have a common type?
>
> I understand what it does, but not why/how it does it, if you 
> get me :-)
>
>     static if (is(typeof(true ? T[0].init : T[1].init) U))
>     {
>         alias CommonType!(U, T[2 .. $]) CommonType;
>     }
>
> (2) Same code -- why is it only necessary to check T[0].init : 
> T[1].init and not vice versa?  (Yes, you can tell I don't 
> really understand the : operator properly:-)

This contains quite a bit of trickery. A ternary expression must 
evaluate to a single, statically known type. Therefore, true ? 
T[0].init : T[1].init will only be a valid expression if there is 
a common type between T[0] and T[1]

 From the spec dlang.org/expression.html:

> Conditional Expressions
> 
> ConditionalExpression:
>     OrOrExpression
>     OrOrExpression ? Expression : ConditionalExpression
> 
> The first expression is converted to bool, and is
> evaluated. If it is true, then the second expression
> is evaluated, and its result is the result of the conditional 
> expression. If it is false, then the third
> expression is evaluated, and its result is the result of the 
> conditional expression. If either the second or third 
> expressions are of type void, then the resulting type is void. 
> Otherwise, the second and third expressions are implicitly 
> converted to a common type which becomes
> the result type of the conditional expression.


If there is a common type then U is declared as an alias of it 
and the is expression returns true.
If there isn't a common type, the ternary expression is an error 
and the is expression will return false.

In the first case we just recursively traverse the type list, in 
the second we declare the common type to be void.


Basically, it's just a wrapper around some compiler magic. All 
the common type calculation is all done by the compiler as a 
convenient effect of the ternary operator.


More information about the Digitalmars-d-learn mailing list