Thread overview | |||||||
---|---|---|---|---|---|---|---|
|
June 29, 2014 Conflict between function and template with the same name | ||||
---|---|---|---|---|
| ||||
I have a question about this example code; import std.stdio; string getByName(string name) { return "smth"; } template getByName(string name) { enum //string getByName = getByName(name); } void main() { writeln(getByName!("name")); } This produces compilation output: /d967/f983.d(13): Error: forward reference of variable getByName /d967/f983.d(19): Error: template instance f983.getByName!"name" error instantiating Uncommenting line *//string* changes message to: Compilation output: /d976/f558.d(13): Error: recursive evaluation of getByName(name) /d976/f558.d(19): Error: template instance f558.getByName!"name" error instantiating Is there any reason why function and template conflict. They using different syntax to *call*. For template we have *!* but for function we don't have it. So why compiler is not able to see the difference? |
June 29, 2014 Re: Conflict between function and template with the same name | ||||
---|---|---|---|---|
| ||||
Posted in reply to Uranuz | On Sunday, 29 June 2014 at 07:16:10 UTC, Uranuz wrote:
> Is there any reason why function and template conflict. They using different syntax to *call*. For template we have *!* but for function we don't have it. So why compiler is not able to see the difference?
I suspect this is by design. The following works, note the dot before the getByName function call:
import std.stdio;
string getByName(string name)
{
return "smth";
}
template getByName(string name)
{
enum getByName = .getByName(name);
}
void main()
{
writeln(getByName!("name"));
}
|
June 29, 2014 Re: Conflict between function and template with the same name | ||||
---|---|---|---|---|
| ||||
Posted in reply to Rene Zwanenburg | > import std.stdio;
>
> string getByName(string name)
> {
> return "smth";
> }
>
> template getByName(string name)
> {
> enum getByName = .getByName(name);
> }
>
>
> void main()
> {
> writeln(getByName!("name"));
> }
Thanks a lot! Very interesting. Do you see any reasoning why this happens?
|
June 29, 2014 Re: Conflict between function and template with the same name | ||||
---|---|---|---|---|
| ||||
Posted in reply to Uranuz | On Sunday, 29 June 2014 at 08:52:36 UTC, Uranuz wrote:
>> import std.stdio;
>>
>> string getByName(string name)
>> {
>> return "smth";
>> }
>>
>> template getByName(string name)
>> {
>> enum getByName = .getByName(name);
>> }
>>
>>
>> void main()
>> {
>> writeln(getByName!("name"));
>> }
>
> Thanks a lot! Very interesting. Do you see any reasoning why this happens?
I think it has to do with variable shadowing. The lookup rules for enums are the same as for variables. Since the getByName enum is declared inside the template scope it takes precedence over the function in the outer scope, even when initializing the enum.
I'm not sure though, hopefully someone a bit more knowledgeable than me comes along to clarify.
Prepending a dot makes the lookup happen in global scope.
|
June 29, 2014 Re: Conflict between function and template with the same name | ||||
---|---|---|---|---|
| ||||
Posted in reply to Rene Zwanenburg | On 06/29/2014 11:31 AM, Rene Zwanenburg wrote: > On Sunday, 29 June 2014 at 08:52:36 UTC, Uranuz wrote: >>> import std.stdio; >>> >>> string getByName(string name) >>> { >>> return "smth"; >>> } >>> >>> template getByName(string name) >>> { >>> enum getByName = .getByName(name); >>> } >>> >>> >>> void main() >>> { >>> writeln(getByName!("name")); >>> } >> >> Thanks a lot! Very interesting. Do you see any reasoning why this >> happens? > > I think it has to do with variable shadowing. The lookup rules for enums > are the same as for variables. Since the getByName enum is declared > inside the template scope it takes precedence over the function in the > outer scope, even when initializing the enum. > > I'm not sure though, hopefully someone a bit more knowledgeable than me > comes along to clarify. > > Prepending a dot makes the lookup happen in global scope. I think it is either a bug or an unnecessary limitation. The following compiles: string s; void writeln(T...)(T args){ s~=args[0]; writeln(args[1..$]); } void writeln(){ s~="\n"; } string getByName()(string name){ return "smth"; } void getByName(){ pragma(msg, getByName!"foo"); } template getByName(string name){ enum getByName = getByName!()(name); } void main(){ pragma(msg,getByName!("name")); writeln("123","1234"); } I.e. calling a different overload from a templated function is supported, instantiating a different overload from a function is supported, instantiating a different overload from template scope is supported, but not calling a different overload from template scope. It's probably left out accidentally. |
Copyright © 1999-2021 by the D Language Foundation