August 02, 2012
module main;

import std.stdio;

immutable double f = 0;

template T(alias a)
{
	auto T = a;
}

int main(string[] argv)
{
	char f = 'a';
	writeln(typeid(T!f));//deduce f as 'a'
	readln();
	return 0;
}

August 02, 2012
On 8/3/12, Zhenya <zheny@list.ru> wrote:
> snip

You mean how to extract the variable name?

import std.stdio;

template T(alias a)
{
    enum string T = __traits(identifier, a);
}

void main(string[] argv)
{
    char f = 'a';
    writeln(T!f);  // writes 'f'
}
August 02, 2012
On Thursday, 2 August 2012 at 22:36:34 UTC, Andrej Mitrovic wrote:
> On 8/3/12, Zhenya <zheny@list.ru> wrote:
>> snip
>
> You mean how to extract the variable name?
>
> import std.stdio;
>
> template T(alias a)
> {
>     enum string T = __traits(identifier, a);
> }
>
> void main(string[] argv)
> {
>     char f = 'a';
>     writeln(T!f);  // writes 'f'
> }
Huh,thank you,I understood.I just thought that by default alias parameter is an identifier.I was surprised then I saw that possible to pass value of variable,which is'nt enum.Could you explain me why it is?
August 02, 2012
Sorry for my terrible english

August 02, 2012
I mean that in ths code

double f = 0;

template T(alias a)
{
	void doit()
	{
		a = 1;
	}
}

int main(string[] argv)
{
	T!f.doit();
	writeln(f);//alias a is'nt 0,alias a is f
	readln();
	return 0;
}
So why if we declared variable whith name 'f' something should change?

August 02, 2012
On 8/3/12, Zhenya <zheny@list.ru> wrote:
> Huh,thank you,I understood.I just thought that by default alias parameter is an identifier.I was surprised then I saw that possible to pass value of variable,which is'nt enum.Could you explain me why it is?

I think alias can be seen as "pass by name". The template gets access to a symbol whatever that symbol is (a variable, a type..). Whether or not you can instantiate the template depends on what you do inside the template, for example the following is all legal because every symbol has a .stringof property:

template Test(alias symbol)
{
    pragma(msg, symbol.stringof);
}

void main()
{
    alias Test!(1) x;

    enum int en = 1;
    alias Test!(en) y;

    int var;
    alias Test!(var) z;
}

But if you change the template so it tries to read what the value of 'symbol' stores you will get an error for the last instantiation:

template Test(alias symbol)
{
    pragma(msg, symbol);
}

void main()
{
    alias Test!(1) x;

    enum int en = 1;
    alias Test!(en) y;   // ok, can be read at compile time

    int var;
    // error: variable var cannot be read at compile time
    alias Test!(var) z;
}
August 02, 2012
On 08/02/2012 04:42 PM, Zhenya wrote:
> I mean that in ths code
>
> double f = 0;
>
> template T(alias a)
> {
> void doit()
> {
> a = 1;
> }
> }
>
> int main(string[] argv)
> {
> T!f.doit();
> writeln(f);//alias a is'nt 0,alias a is f

Yes, the a in template T is an alias of f.

> So why if we declared variable whith name 'f' something should change?

Getting back to your original code, the problem with the following line:

template T(alias a)
{
    auto T = a;    // <-- Error
}

Since templates are compile-time features, T!f must be evaluated at compile time and the template's value must be equal to the alias a.

But you are not instantiating the template with a compile-time entity:

    char f = 'a';
    writeln(typeid(T!f)); // <-- can't work

You must make f evaluatable at compile-time:

import std.stdio;

template T(alias a)
{
    auto T = a;
}

int main(string[] argv)
{
    enum f = 'a';      // <-- enum works
    assert(T!f == 'a');

    return 0;
}

Another option is to define f as immutable:

    immutable f = 'a';

Ali

August 03, 2012
Thank you,guys,now all became clear to me.

Top | Discussion index | About this forum | D home