Where does "U" in Rebindable.Rebindable come from?
Simen Kjærås
simen.kjaras at gmail.com
Thu Mar 29 16:09:06 PDT 2012
On Thu, 29 Mar 2012 22:15:41 +0200, simendsjo <simendsjo at gmail.com> wrote:
> If you look at the struct, it uses the type U in, among others, the
> union.
>
> The only place I could see U referenced is in the first static if, but I
> cannot recreate this behavior:
> void main() {
> static if(is(int X == const(U), U))
Ah, the magic of isExpressions...
What happens here is the isExpression asks 'if X is an int, does it
match the pattern const(U), where U is some type?'
Of course, there is no U for which const(U) == int, so the isExpresion
returns false, and your static assert triggers.
> static if (!is(T X == const(U), U) && !is(T X == immutable(U), U))
Again, 'is there a U such that const(U) == T?', then the same for
immutable(U). In other words - 'is T mutable?'.
The reason the U is there is to explain to the compiler that we're
talking about this specific U, not some other U that may be defined
elsewhere in the program.
The same pattern is used in std.typecons.isTuple:
template isTuple(T)
{
static if (is(Unqual!T Unused : Tuple!Specs, Specs...))
{
enum isTuple = true;
}
else
{
enum isTuple = false;
}
}
It can also be extended to other templates:
struct Foo() {}
struct Foo(int n) {}
struct Foo(T) {}
template FooType(T) {
static if (is(Unqual!T Unused : Foo!())) {
enum FooType = "Type 1";
} else static if (is(Unqual!T Unused : Foo!n, int n)) {
enum FooType = "Type 2";
} else static if (is(Unqual!T Unused : Foo!U, U)) {
enum FooType = "Type 3";
} else {
enum FooType = "No Foo!";
}
}
Hope this helps.
More information about the Digitalmars-d-learn
mailing list