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