Thread overview | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
|
June 20, 2015 Erroneous "auto can only be used for template function parameters"? | ||||
---|---|---|---|---|
| ||||
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. |
June 20, 2015 Re: Erroneous "auto can only be used for template function parameters"? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Yuxuan Shui | 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.
|
June 21, 2015 Re: Erroneous "auto can only be used for template function parameters"? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Yuxuan Shui | 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.
|
June 21, 2015 Re: Erroneous "auto can only be used for template function parameters"? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam D. Ruppe | 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.
|
June 21, 2015 Re: Erroneous "auto can only be used for template function parameters"? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam D. Ruppe | 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)
|
June 22, 2015 Re: Erroneous "auto can only be used for template function parameters"? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Yuxuan Shui | 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
|
June 22, 2015 Re: Erroneous "auto can only be used for template function parameters"? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | 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?
|
June 22, 2015 Re: Erroneous "auto can only be used for template function parameters"? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Yuxuan Shui | 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
|
June 22, 2015 Re: Erroneous "auto can only be used for template function parameters"? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Yuxuan Shui | 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) {
}
}
|
June 22, 2015 Re: Erroneous "auto can only be used for template function parameters"? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Yuxuan Shui | 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
|
Copyright © 1999-2021 by the D Language Foundation