Re: Erroneous "auto can only be used for template function parameters"?

2015-06-22 Thread Yuxuan Shui via Digitalmars-d-learn

On Saturday, 20 June 2015 at 01:50:11 UTC, Yuxuan Shui wrote:

Try to compile this code snippet:

import std.traits;
template a(R) {
auto a(S)(auto ref R i) {
return cast(S)i*2;
}
}
template ReturnTypeEx(alias A, B) {
alias ReturnTypeEx = ReturnType!(A!B);
}
template b(alias R) {
int b(S)(S i) {
alias Ra = ReturnTypeEx!(R, S);
return cast(int)R!S(i);
}
}
void main() {
alias bb = b!(a!ulong);
pragma(msg, ReturnTypeEx!(bb, int));
}

DMD reports:
sadf.d(3): Error: auto can only be used for template function 
parameters
sadf.d(8): Error: template instance sadf.a!ulong.A!int error 
instantiating

sadf.d(12):instantiated from here: ReturnTypeEx!(a, int)
sadf.d(8):instantiated from here: A!int
sadf.d(18):instantiated from here: ReturnTypeEx!(b, int)
sadf.d(18):while evaluating pragma(msg, 
ReturnTypeEx!(b, int))


But a(S)(auto ref R) is indeed a template function, so I don't 
understand.


After more experimenting, here's what I got. This time no nested 
templates are involved, this seems more likely an 'auto ref' bug.


import std.traits, std.range;

void a(S)(auto ref S i) { }
void b(S)(auto ref S i) if (isInputRange!S) { }
void c(S)(ref S i) if (isInputRange!S) { }

void devil(alias S)() { }

void main() {
a!string(""); //Works  <--- This line affects the result of 
devil!(a!string)

b!string(""); //Works

//Next line is weird, it:
//1. Err, 'auto ref can only be used with template function', 
if 'a' is not

//   instantiated with 'a!string' first
//2. Works, if 'a!string' is done first
alias x = devil!(a!string);

alias xx = devil!(b!string); //Err, template doesn't match

alias xxx = devil!(c!string); //Works
}

I'm using DMD 2.067.1


Re: Erroneous "auto can only be used for template function parameters"?

2015-06-22 Thread Jesse Phillips via Digitalmars-d-learn

On Sunday, 21 June 2015 at 02:37:59 UTC, Yuxuan Shui wrote:

On Sunday, 21 June 2015 at 01:26:51 UTC, Adam D. Ruppe wrote:

On Saturday, 20 June 2015 at 01:50:11 UTC, Yuxuan Shui wrote:
auto ref R) is indeed a template function, so I don't 
understand.


But R is not a parameter on the function itself. It comes from 
the outside template.


Move it to the inside template, rewrite it as:

auto a(S, R)(auto ref R i) {
return cast(S)i*2;
}

and you should get further.


Also the same error persists even if I change 'a' to

auto a(S)(auto ref S i)


I'm not reproducing in DMD 2.067:

void main() {
int m;
a!int(m);
}
template a(R) {
auto a(S)(auto ref S i) {
}
}

Note that since template 'a' and function template 'a' have the 
same name you're invoking IFTI, otherwise the code would look 
like:


void main() {
int m;
z!int.a(m);
}
template z(R) {
auto a(S)(auto ref S i) {
}
}



Re: Erroneous "auto can only be used for template function parameters"?

2015-06-22 Thread Steven Schveighoffer via Digitalmars-d-learn

On 6/22/15 1:37 PM, Yuxuan Shui wrote:

On Monday, 22 June 2015 at 13:49:21 UTC, Steven Schveighoffer wrote:

On 6/20/15 10:26 PM, Yuxuan Shui wrote:

On Sunday, 21 June 2015 at 01:26:51 UTC, Adam D. Ruppe wrote:

On Saturday, 20 June 2015 at 01:50:11 UTC, Yuxuan Shui wrote:

auto ref R) is indeed a template function, so I don't understand.


But R is not a parameter on the function itself. It comes from the
outside template.

Move it to the inside template, rewrite it as:

auto a(S, R)(auto ref R i) {
return cast(S)i*2;
}

and you should get further.


But surely nested template should be able to access outer template's
parameter.


If you have to instantiate it to see how to instantiate it, it doesn't
work. General rule of thumb on templates. IFTI only works at one level.


I can't see any IFTI in my code, can you point it out?


Sorry, I misunderstood what is happening here. I don't know what the 
rules are for auto ref for nested template functions, or for explicit 
instantiation.


-Steve


Re: Erroneous "auto can only be used for template function parameters"?

2015-06-22 Thread Yuxuan Shui via Digitalmars-d-learn
On Monday, 22 June 2015 at 13:49:21 UTC, Steven Schveighoffer 
wrote:

On 6/20/15 10:26 PM, Yuxuan Shui wrote:

On Sunday, 21 June 2015 at 01:26:51 UTC, Adam D. Ruppe wrote:

On Saturday, 20 June 2015 at 01:50:11 UTC, Yuxuan Shui wrote:
auto ref R) is indeed a template function, so I don't 
understand.


But R is not a parameter on the function itself. It comes 
from the

outside template.

Move it to the inside template, rewrite it as:

auto a(S, R)(auto ref R i) {
return cast(S)i*2;
}

and you should get further.


But surely nested template should be able to access outer 
template's

parameter.


If you have to instantiate it to see how to instantiate it, it 
doesn't work. General rule of thumb on templates. IFTI only 
works at one level.


-Steve


I can't see any IFTI in my code, can you point it out?


Re: Erroneous "auto can only be used for template function parameters"?

2015-06-22 Thread Steven Schveighoffer via Digitalmars-d-learn

On 6/20/15 10:26 PM, Yuxuan Shui wrote:

On Sunday, 21 June 2015 at 01:26:51 UTC, Adam D. Ruppe wrote:

On Saturday, 20 June 2015 at 01:50:11 UTC, Yuxuan Shui wrote:

auto ref R) is indeed a template function, so I don't understand.


But R is not a parameter on the function itself. It comes from the
outside template.

Move it to the inside template, rewrite it as:

auto a(S, R)(auto ref R i) {
return cast(S)i*2;
}

and you should get further.


But surely nested template should be able to access outer template's
parameter.


If you have to instantiate it to see how to instantiate it, it doesn't 
work. General rule of thumb on templates. IFTI only works at one level.


-Steve


Re: Erroneous "auto can only be used for template function parameters"?

2015-06-20 Thread Yuxuan Shui via Digitalmars-d-learn

On Sunday, 21 June 2015 at 01:26:51 UTC, Adam D. Ruppe wrote:

On Saturday, 20 June 2015 at 01:50:11 UTC, Yuxuan Shui wrote:
auto ref R) is indeed a template function, so I don't 
understand.


But R is not a parameter on the function itself. It comes from 
the outside template.


Move it to the inside template, rewrite it as:

auto a(S, R)(auto ref R i) {
return cast(S)i*2;
}

and you should get further.


Also the same error persists even if I change 'a' to

auto a(S)(auto ref S i)


Re: Erroneous "auto can only be used for template function parameters"?

2015-06-20 Thread Yuxuan Shui via Digitalmars-d-learn

On Sunday, 21 June 2015 at 01:26:51 UTC, Adam D. Ruppe wrote:

On Saturday, 20 June 2015 at 01:50:11 UTC, Yuxuan Shui wrote:
auto ref R) is indeed a template function, so I don't 
understand.


But R is not a parameter on the function itself. It comes from 
the outside template.


Move it to the inside template, rewrite it as:

auto a(S, R)(auto ref R i) {
return cast(S)i*2;
}

and you should get further.


But surely nested template should be able to access outer 
template's parameter.


Re: Erroneous "auto can only be used for template function parameters"?

2015-06-20 Thread Adam D. Ruppe via Digitalmars-d-learn

On Saturday, 20 June 2015 at 01:50:11 UTC, Yuxuan Shui wrote:
auto ref R) is indeed a template function, so I don't 
understand.


But R is not a parameter on the function itself. It comes from 
the outside template.


Move it to the inside template, rewrite it as:

auto a(S, R)(auto ref R i) {
return cast(S)i*2;
}

and you should get further.


Re: Erroneous "auto can only be used for template function parameters"?

2015-06-19 Thread Yuxuan Shui via Digitalmars-d-learn

On Saturday, 20 June 2015 at 01:50:11 UTC, Yuxuan Shui wrote:

Try to compile this code snippet:

import std.traits;
template a(R) {
auto a(S)(auto ref R i) {
return cast(S)i*2;
}
}
template ReturnTypeEx(alias A, B) {
alias ReturnTypeEx = ReturnType!(A!B);
}
template b(alias R) {
int b(S)(S i) {
alias Ra = ReturnTypeEx!(R, S);
return cast(int)R!S(i);
}
}
void main() {
alias bb = b!(a!ulong);
pragma(msg, ReturnTypeEx!(bb, int));
}

DMD reports:
sadf.d(3): Error: auto can only be used for template function 
parameters
sadf.d(8): Error: template instance sadf.a!ulong.A!int error 
instantiating

sadf.d(12):instantiated from here: ReturnTypeEx!(a, int)
sadf.d(8):instantiated from here: A!int
sadf.d(18):instantiated from here: ReturnTypeEx!(b, int)
sadf.d(18):while evaluating pragma(msg, 
ReturnTypeEx!(b, int))


But a(S)(auto ref R) is indeed a template function, so I don't 
understand.


Another thing I discovered is instantiation like this: (a!T)!S 
will result in "C style cast illegal", which is clearly wrong 
because this is not a cast, (a!T) is not necessarily a type.


Erroneous "auto can only be used for template function parameters"?

2015-06-19 Thread Yuxuan Shui via Digitalmars-d-learn

Try to compile this code snippet:

import std.traits;
template a(R) {
auto a(S)(auto ref R i) {
return cast(S)i*2;
}
}
template ReturnTypeEx(alias A, B) {
alias ReturnTypeEx = ReturnType!(A!B);
}
template b(alias R) {
int b(S)(S i) {
alias Ra = ReturnTypeEx!(R, S);
return cast(int)R!S(i);
}
}
void main() {
alias bb = b!(a!ulong);
pragma(msg, ReturnTypeEx!(bb, int));
}

DMD reports:
sadf.d(3): Error: auto can only be used for template function 
parameters
sadf.d(8): Error: template instance sadf.a!ulong.A!int error 
instantiating

sadf.d(12):instantiated from here: ReturnTypeEx!(a, int)
sadf.d(8):instantiated from here: A!int
sadf.d(18):instantiated from here: ReturnTypeEx!(b, int)
sadf.d(18):while evaluating pragma(msg, ReturnTypeEx!(b, 
int))


But a(S)(auto ref R) is indeed a template function, so I don't 
understand.