Thread overview
Template with equivalent function names
Aug 16, 2010
Andrej Mitrovic
Aug 16, 2010
Jonathan M Davis
Aug 16, 2010
Simen kjaeraas
Aug 16, 2010
Andrej Mitrovic
August 16, 2010
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

August 16, 2010
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
August 16, 2010
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
August 16, 2010
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