Mixin and function template?
Frits van Bommel
fvbommel at REMwOVExCAPSs.nl
Thu Mar 1 18:03:08 PST 2007
renoX wrote:
> Frits van Bommel a écrit :
>> renoX wrote:
>>> char[] sputf(A...)()
>>> {
>>> return "std.string.format("~Fmt!(A) ~ ");";
>>> }
>>>
>>> And still call it like you do above?
>>> It doesn't work when I try to do this, I don't understand why..
>>
>> For one thing, the ';' shouldn't be there.
>
> Weird, the template that I had already for the 'writef equivalent' was:
> template putf(A...)
> {
> const char[] putf = "writef(" ~ Fmt!(A) ~ ");";
> }
> Here the ';' didn't create a problem, it's string that in the sputf
> template function it creates a problem..
There are three kinds of mixins[1]: mixin declarations, mixin statements
and mixin expressions. Your putf string is used as a mixin statement,
while the sputf string is used as a mixin expression.
See http://www.digitalmars.com/d/changelog.html#new1_005 for the spec
links, but essentially mixin statements generate statements (including
any terminating ';'s) while mixin expressions just generate
(sub)expressions, which don't contain ';'s.
[1] excluding template mixins, which are a different beast altogether.
>> Then you get this:
>> ---
>> import std.stdio;
>> import std.string;
>>
>> /** dummy Fmt!() for testing. This example assumes it accepts a
>> * tuple and returns format() parameters in string form.
>> */
>> template Fmt(A...) {
>> const char[] Fmt = `"%d", x`;
>> }
>>
>> char[] sputf(A...)()
>> {
>> return "std.string.format(" ~ Fmt!(A) ~ ")";
>> }
>>
>> void main(char[][] args) {
>> char[] ret;
>> int x = 2007;
>> ret = mixin(sputf!("%d{x}"));
>> writefln("%s", ret);
>> }
>> ---
>> which seems to work.
>
> Yes, but what is a bit strange is that if x is an int variable
> res = mixin(sputf!("%d",x)); fails (it works if x is a const int)
> but mixin(putf!("%d",x)); works (putf being the template given above).
The behaviors differ? That's a bit weird...
They both use template parameters, so they should have the exact same
restrictions AFAIK.
[a bit of research later]
I think this is a restriction of compile-time function evaluation.
From http://www.digitalmars.com/d/function.html#interpretation :
---
expressions in the function may not:
[snip]
* reference any global state or variables
* reference any local static variables
[snip]
---
Those /could/ be interpreted to disallow alias template parameter usage...
Luckily the fix is easy, just transform it to be similar to your putf
template to avoid CTFE:
---
template sputf(A...)
{
const sputf = "std.string.format(" ~ Fmt!(A) ~ ")";
}
---
works perfectly fine, even with non-constant integer variables as
parameters.
And the call syntax didn't even change :).
More information about the Digitalmars-d-learn
mailing list