www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Template with equivalent function names

reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
This isn't a question but more of an observation. Here's an interesting
template from the docs:

template Foo(T, R...)
{
    void Foo(T t, R r)
    {
	writeln(t);
	static if (r.length)	// if more arguments
	    Foo(r);		// do the rest of the arguments
    }
}

void main()
{
    Foo(1, 'a', 6.8);
}

What really intrigues me here is not the tuples which I already get, but the
fact that Foo is a function template. But if I remove the inner Foo() function
then it's not a function template anymore so the call in main won't work. The
inner function must have the same name as the template, apparently (it doesn't
even state this in the docs from what I can tell!).

There seem to be plenty of ways of making templates, sometimes you explicitly
add the template keyword, sometimes not.. I kind of wish the syntax was more
unified in this regard.

Well anyway, that page (http://www.digitalmars.com/d/2.0/template.html) reveals
some really powerfull stuff you can do with templates. If only template error
messages were as exciting to look at! :p
Aug 15 2010
next sibling parent Jonathan M Davis <jmdavisprog gmail.com> writes:
On Sunday 15 August 2010 20:18:27 Andrej Mitrovic wrote:
 This isn't a question but more of an observation. Here's an interesting
 template from the docs:
 
 template Foo(T, R...)
 {
     void Foo(T t, R r)
     {
 	writeln(t);
 	static if (r.length)	// if more arguments
 	    Foo(r);		// do the rest of the arguments
     }
 }
 
 void main()
 {
     Foo(1, 'a', 6.8);
 }
 
 What really intrigues me here is not the tuples which I already get, but
 the fact that Foo is a function template. But if I remove the inner Foo()
 function then it's not a function template anymore so the call in main
 won't work. The inner function must have the same name as the template,
 apparently (it doesn't even state this in the docs from what I can tell!).
 
 There seem to be plenty of ways of making templates, sometimes you
 explicitly add the template keyword, sometimes not.. I kind of wish the
 syntax was more unified in this regard.
 
 Well anyway, that page (http://www.digitalmars.com/d/2.0/template.html)
 reveals some really powerfull stuff you can do with templates. If only
 template error messages were as exciting to look at! :p
TDPL does discuss it, and it's highly useful. Of course, in this case, you might as well make the function itself a template function instead of putting it in a template, but it's highly useful and definitely used in Phobos to have a template with the same name as one of its members. Functions like Format!() would be a prime example. Usually, the member with the same name is an enum which then replaces the template when instantiatied. It's _highly_ useful for generating stuff at compile-time. Regardless, I'm sure that the docs could be updated and fleshed out with regards to templates. I'd guess that part of the problem is that the more experienced D users pretty much never read them, and the folks who would be qualified and arguably have the responsibility to keep them up-to-date are very busy with other D-related stuff that needs doing. - Jonathan M Davis
Aug 15 2010
prev sibling parent reply "Simen kjaeraas" <simen.kjaras gmail.com> writes:
Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:

 This isn't a question but more of an observation. Here's an interesting  
 template from the docs:

 template Foo(T, R...)
 {
     void Foo(T t, R r)
     {
 	writeln(t);
 	static if (r.length)	// if more arguments
 	    Foo(r);		// do the rest of the arguments
     }
 }

 void main()
 {
     Foo(1, 'a', 6.8);
 }

 What really intrigues me here is not the tuples which I already get, but  
 the fact that Foo is a function template. But if I remove the inner  
 Foo() function then it's not a function template anymore so the call in  
 main won't work. The inner function must have the same name as the  
 template, apparently (it doesn't even state this in the docs from what I  
 can tell!).
It is in fact mentioned, but not touted as an impressive feature: "If a template declares exactly one member, and that member is a function with the same name as the template, it is a function template declaration."[1] The same is true for struct, union, and class templates, as well as 'Implicit Template Properties', meaning any template with exactly one member, if that member has the same name as the template itself. In fact, shorthand eponymous templates, like struct foo(T){} or void bar(T)(); translate internally to template foo(T){ struct foo{} } and template bar(T){ void bar(){} }. Other common patterns used with this trick are compile-time constants: template foo!(int n) { enum foo = n; } and alias types: template foo(int n, T...) { alias T[n] foo; } [1]: http://www.digitalmars.com/d/2.0/template.html#function-templates -- Simen
Aug 16 2010
parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
Ah, you're right it does mention it, it was further down below from that
template function. Thanks guys.

Simen kjaeraas Wrote:

 Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:
 
 This isn't a question but more of an observation. Here's an interesting  
 template from the docs:

 template Foo(T, R...)
 {
     void Foo(T t, R r)
     {
 	writeln(t);
 	static if (r.length)	// if more arguments
 	    Foo(r);		// do the rest of the arguments
     }
 }

 void main()
 {
     Foo(1, 'a', 6.8);
 }

 What really intrigues me here is not the tuples which I already get, but  
 the fact that Foo is a function template. But if I remove the inner  
 Foo() function then it's not a function template anymore so the call in  
 main won't work. The inner function must have the same name as the  
 template, apparently (it doesn't even state this in the docs from what I  
 can tell!).
It is in fact mentioned, but not touted as an impressive feature: "If a template declares exactly one member, and that member is a function with the same name as the template, it is a function template declaration."[1] The same is true for struct, union, and class templates, as well as 'Implicit Template Properties', meaning any template with exactly one member, if that member has the same name as the template itself. In fact, shorthand eponymous templates, like struct foo(T){} or void bar(T)(); translate internally to template foo(T){ struct foo{} } and template bar(T){ void bar(){} }. Other common patterns used with this trick are compile-time constants: template foo!(int n) { enum foo = n; } and alias types: template foo(int n, T...) { alias T[n] foo; } [1]: http://www.digitalmars.com/d/2.0/template.html#function-templates -- Simen
Aug 16 2010