On Saturday, 3 August 2013 at 11:27:30 UTC, andrea9940 wrote:
Hello D world, I have just started using templates and mixins to generate some boilerplate code and I have found a little ambiguity:

This code compiles fine:

private template genTypes()
{
        string eval() { ... }
        const(char[]) genTypes = eval();
}
mixin(genTypes!());  // Working

But this does not, why ?

private template genTypes()
{
        string eval() { ... }
        string genTypes = eval();
}
mixin(genTypes!()); // Error: variable genTypes cannot be read at compile time

I would expect both version to work.

( complete code at http://pastebin.com/FhmrgmZZ )

It is probably because you did not write what you meant.

First, take notice that:
const(char[]) //(1)
is different from
const(char)[] //(2)

1 is "full const", which means the compiler, since it is smart enough, is able to say "hey, I can evaluate this variable at compile time". In 2, however, while the "payload" of the array is const, the array itself isn't. For example, you'll notice this is perfectly legal:

private template genTypes()
{
  string eval() { return "hello"; }
  string genTypes = eval();
}

void main()
{
    genTypes!() = "world";
}

As you can see, genTypes just resolves to a GLOBAL string, and not to a manifest constant string. Because of this, mixin in genTypes is not possible.

What you probably meant to write was:

private template genTypes()
{
  string eval() { ... }
        enum string genTypes = eval();
  //or just
  enum genTypes = eval();
}

This means genTypes will resolve statically to the string returned by eval, and you can mix that in.

If you use "const" or "immutable" instead of "enum", then the compiler will also generate a reference-able string for genTypes, which you may or may not want. Hint, if in doubt, use enum, that's what phobos does 100% of the time.

Reply via email to