Can't declare a "template parameter which takes anything"

Jari-Matti Mäkelä jmjmak at utu.fi.invalid
Mon Mar 17 08:49:15 PDT 2008


On Mon, 17 Mar 2008, Russell Lewis wrote:

> I'd like to propose that we need a template parameter syntax which means 
> "this parameter can be anything...type, alias, or value."  Currently, an 
> unadorned parameter is required to be a type, and it cannot take an alias or 
> value parameter.
>
> In a perfect world, I would suggest that unadorned parameters should take 
> this role, and that people who wanted templates that *only* took types would 
> need to adorn their parameters with "type" (a new keyword).  However, that's 
> a breaking change (few people would be affected, I think, but they would be 
> affected in subtle ways) so I would be willing to settle for a keyword like 
> "anything" which would declare these new types of parameters.
>
>
>
> BACKGROUND
>
> I wrote the following innocuous-seeming template because I often want to 
> apply the same template to a number of parameters:
>
> BEGIN CODE
> 	template template_foreach(TEMPLATE)
> 	{
> 	  alias Tuple!() template_foreach;
> 	}
>
> 	template template_foreach(TEMPLATE, T,TPL...)
> 	{
> 	  alias Tuple!(TEMPLATE!(T), template_foreach!(TEMPLATE, TPL))
> 	        template_foreach;
> 	}
> END CODE
>
> Looks ok to me.  But then I get errors when I try to use it in 
> seemingly-simple ways:
>
> BEGIN CODE
> 	template my_template(...whatever...) { ... whatever ... }
>
> 	void foo() {}
>
> 	alias template_foreach!(my_template, 1)   bar;
> 	alias template_foreach!(my_template, foo) baz;
> END CODE
>
> Both of those "alias" declarations give "template instance 
> template_foreach!(my_template, <arg>) does not match any template 
> declaraion."  Huh?
>
> The reason for this is that the parameter T, in the 2nd template_foreach() 
> declaration, is assumed that it *MUST BE A TYPE*. You can't pass it aliases 
> or values.  Of course, if you rewrite template_foreach() to use tuples, then 
> it works:
>
> BEGIN CODE
> 	template template_foreach(TEMPLATE, TPL...)
> 	{
> 		static if(TPL.length == 0)
> 		   alias Tuple!() template_foreach;
> 		else
> 		   alias Tuple!(TEMPLATE!(TPL[0]),
> 		                template_foreach!(TEMPLATE, TPL[1..$])
> 		         template_foreach;
> 	}
> END CODE
>
> The reason that this works is that tuples can take any sort of thing as their 
> elements.  But is this new template easier to read?  And will it make sense 
> to a novice D programmer what is wrong?  It took me hours, if not days, to 
> finally understand this.

I don't know what kind of plans Walter has, but I'm hoping that the macros 
could be used when arbitrary arguments are needed - they could match 
different kinds of AST subtrees. It would still make perfectly sense to 
use templates when operating with types. If the example above only creates 
new parametrized types, you could make it more readable by using a compile 
time map metafunction.

But yea, I agree having arguments of type 'type' is a bit problematic. It 
might be a better idea to make it a special case just like values, 
aliases, and tuples are, and having a "tuple of size 1" as a default.



More information about the Digitalmars-d mailing list