digitalmars.D.learn - Eponymous templates ambiguity
- andrea9940 (20/20) Aug 03 2013 Hello D world, I have just started using templates and mixins to
- bearophile (28/29) Aug 03 2013 Simpler code:
- monarch_dodra (37/57) Aug 03 2013 It is probably because you did not write what you meant.
- andrea9940 (1/1) Aug 03 2013 Thanks to both of you !
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 )
Aug 03 2013
andrea9940:( complete code at http://pastebin.com/FhmrgmZZ )Simpler code: import std.stdio; import std.typecons; private immutable extensionTable = [ ["WGL_ARB_make_current_read", "void function(int, int, int)", "wglMakeContextCurrentARB", "void function()", "wglGetCurrentReadDCARB"], ["WGL_ARB_pixel_format_float"], ["WGL_ARB_create_context", "void function(int, int, int)", "wglCreateContextAttribsARB"], ]; string eval() { string code; foreach (const array; extensionTable) for (uint index = 1; index < array.length; index += 2) code ~= "alias nothrow " ~ array[index] ~ " da_" ~ array[index + 1] ~ ";"; return code; } mixin(eval); void main() { assert(is(da_wglCreateContextAttribsARB)); } Bye, bearophile
Aug 03 2013
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.
Aug 03 2013









"bearophile" <bearophileHUGS lycos.com> 