Mixin and function template?
renoX
renosky at free.fr
Fri Mar 2 00:32:05 PST 2007
Frits van Bommel a écrit :
> 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 :).
Great!
Thanks a lot!
renoX
More information about the Digitalmars-d-learn
mailing list