October 24, 2005
In the D vs C++ section, there's an example of a factorial function.
It mentions that it's taking advantage of promotion of single template members to the enclosing name space:

Listing (1)
------------------------
template factorial(int n)
{
    enum { factorial = n * .factorial!(n-1) }
}

template factorial(int n : 1)
{
    enum { factorial = 1 }
}
-------------------------
I'm trying to do this function using static if instead of specialisation. Indeed, it is possible. But it seems that this promotion does not occur in the presence of static if. Even in the trivial case where the condition is always true:

Listing (2)
-------------
template factorial(int n)
{
  static if (1) {
      enum { factorial = n * .factorial!(n-1) }
  }
}
-------------

However, I'm able to get it to work by using a wrapper template:

Listing(3)
---------
template Factorial(int n)
{
  static if (n==1) const int Factorial=1;
         else      const int Factorial = n * .Factorial!(n-1).Factorial;
}

template factorial(int n)
{
  static int factorial = Factorial!(n).Factorial;
}
---------

Now, if this promotion worked with static if, we could write the factorial as:

Listing (4)
----------
template factorial(int n)
{
   static if (n==1) const int factorial = 1;
          else      const int factorial = n * .factorial!(n-1);
}
----------

which totally leaves the C++ version for dead -- no specialisation required, and it uses const ints instead of those stupid enums (incidentally, this means it's not restricted to integer types!)

(Incidentally, I also notice that in Listing(1) still works if you leave out the ".", which is supposed to access the global template instead of the enum. Listing (3) requires the ".", I'm not sure what the difference is, but maybe it would be optional in listing (4)).

I don't know I'm describing a bug/limitation, or a feature request.
I'm inclined to think it's a bug, because it also applies to the version statement:

template a(int n)
{
  version(all) {
    const int a=27;
  }
}

int main()
{
writefln(a!(7));
return 0;
}

bug.d(10): voids have no value.
October 24, 2005
It's a limitation, not a bug, but I think I can fix it. -Walter