www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Template alias parameter does not accept types

reply "ref2401" <refactor24 gmail.com> writes:
Version D 2.062
http://dlang.org/template.html#TemplateAliasParameter
Is is said in the documentation that is's possible but i get 
compile time error.

template GetString(alias Arg)
{
	enum string GetString = Arg.stringof;
}

void main(string[] argv)
{
	writeln(GetString!"1234");
	writeln(GetString!18);
	
	writeln(GetString!int); // Error: template instance 
GetString!(int)
				// GetString!(int) does not match template
				// declaration GetString(alias Arg)
	
	readln();
}
May 09 2013
next sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
ref2401:

 template GetString(alias Arg)
 {
 	enum string GetString = Arg.stringof;
 }
...
 	writeln(GetString!int); // Error: template instance
Template alias arguments don't yet accept built-in types as int. It will be fixed. Bye, bearophile
May 09 2013
parent reply "Dicebot" <m.strashun gmail.com> writes:
On Thursday, 9 May 2013 at 11:19:38 UTC, bearophile wrote:
 It will be fixed.
Ugh, proof-link? I have always thought it is by design and that actually makes sense.
May 09 2013
parent reply "Kenji Hara" <k.hara.pg gmail.com> writes:
On Thursday, 9 May 2013 at 12:09:03 UTC, Dicebot wrote:
 On Thursday, 9 May 2013 at 11:19:38 UTC, bearophile wrote:
 It will be fixed.
Ugh, proof-link? I have always thought it is by design and that actually makes sense.
AFAIK, there is no plan for fix. The behavior is currently a part of language design. Kenji Hara
May 09 2013
parent "bearophile" <bearophileHUGS lycos.com> writes:
Kenji Hara:

 AFAIK, there is no plan for fix. The behavior is currently a 
 part of language design.
Considering matters of D semantic uniformity, and the code shown by Dicebot: template Hello(T...) if (T.length == 1) { static if (is(T[0])) // ... else // ... } Then maybe the current behavior is worth reconsidering. Bye, bearophile
May 09 2013
prev sibling next sibling parent "Anonimous" <tr1 google.com> writes:
On Thursday, 9 May 2013 at 10:59:02 UTC, ref2401 wrote:
 Version D 2.062
 http://dlang.org/template.html#TemplateAliasParameter
 Is is said in the documentation that is's possible but i get 
 compile time error.

 template GetString(alias Arg)
 {
 	enum string GetString = Arg.stringof;
 }

 void main(string[] argv)
 {
 	writeln(GetString!"1234");
 	writeln(GetString!18);
 	
 	writeln(GetString!int); // Error: template instance 
 GetString!(int)
 				// GetString!(int) does not match template
 				// declaration GetString(alias Arg)
 	
 	readln();
 }
You just can't pass by alias built-in types like int or char Workaround: import std.stdio; template GetString(Arg...) if(Arg.length == 1) { enum string GetString = Arg[0].stringof; } void main(string[] argv) { writeln(GetString!"1234"); writeln(GetString!18); writeln(GetString!int); // Error: template instance GetString!(int) // GetString!(int) does not match template // declaration GetString(alias Arg) readln(); }
May 09 2013
prev sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Thu, 09 May 2013 06:58:57 -0400, ref2401 <refactor24 gmail.com> wrote:

 Version D 2.062
 http://dlang.org/template.html#TemplateAliasParameter
 Is is said in the documentation that is's possible but i get compile  
 time error.

 template GetString(alias Arg)
 {
 	enum string GetString = Arg.stringof;
 }

 void main(string[] argv)
 {
 	writeln(GetString!"1234");
 	writeln(GetString!18);
 	
 	writeln(GetString!int); // Error: template instance GetString!(int)
 				// GetString!(int) does not match template
 				// declaration GetString(alias Arg)
 	
 	readln();
 }
Others have answered, but the technical issue is that alias accepts a *symbol*, int is a *keyword*. Annoying, I know, but I don't see how the compiler can make sense of it, the way it is built. Keywords are special and must go in the right places. You can alias int, and it works: alias int intalias; writeln(GetString!intalias); // writes "intalias" You can also overload GetString to accept builtin types: template GetString(T) if (is(T == int) || is(T == float) || ...) { enum string GetString = T.stringof; } There may even already be a template for detecting a builtin type, not sure. On Thu, 09 May 2013 07:19:37 -0400, bearophile <bearophileHUGS lycos.com> wrote:
 Template alias arguments don't yet accept built-in types as int. It will  
 be fixed.
I don't think this is true, alias strictly accepts symbols or literals, not keywords. Do you have evidence of an official statement to the contrary? -Steve
May 09 2013
next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
Steven Schveighoffer:

 Do you have evidence of an official statement to the contrary?
Here I don't have evidence, just faith :-) Bye, bearophile
May 09 2013
prev sibling parent reply "Dicebot" <m.strashun gmail.com> writes:
On Thursday, 9 May 2013 at 13:27:35 UTC, Steven Schveighoffer 
wrote:
 template GetString(T) if (is(T == int) || is(T == float) || ...)
 {
    enum string GetString = T.stringof;
 }
Current idiomatic D way to handle both built-in types and symbols looks like this: template Hello(T...) if (T.length == 1) { static if (is(T[0])) // ... else // ... } I actually don't understand why it accepts literals as those are not symbols and, for example, you can't attach UDA to literal.
May 09 2013
parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Thu, 09 May 2013 09:38:29 -0400, Dicebot <m.strashun gmail.com> wrote:

 On Thursday, 9 May 2013 at 13:27:35 UTC, Steven Schveighoffer wrote:
 template GetString(T) if (is(T == int) || is(T == float) || ...)
 {
    enum string GetString = T.stringof;
 }
Current idiomatic D way to handle both built-in types and symbols looks like this: template Hello(T...) if (T.length == 1) { static if (is(T[0])) // ... else // ... } I actually don't understand why it accepts literals as those are not symbols and, for example, you can't attach UDA to literal.
I think it was a happy accident, or else a relaxation of the rules to allow more flexibility. Possibly the same reason could be used to relax the rules again. But I think it would be a more difficult prospect in the compiler. alias cannot accept literals in a normal alias statement. But what allowing it for template alias parameters does is enable the whole std.algorithm acceptance of a string literal for function lambdas. Arguably, this is no longer needed due to the new lambda syntax (but I think we have found other uses for it). It has also caused some headaches: map!"a.x"(foo) is a different instantiation with identical code to: map!" a.x"(foo) -Steve
May 09 2013
parent reply "Dicebot" <m.strashun gmail.com> writes:
Feels like I am the only one who wants to restrict rules, not 
relax them =/

But, erm, you don't need alias accepting literals for old syntax! 
Strings are valid as template value parameters: 
http://dpaste.1azy.net/54e5d3f2
May 09 2013
parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Thu, 09 May 2013 10:00:45 -0400, Dicebot <m.strashun gmail.com> wrote:

 Feels like I am the only one who wants to restrict rules, not relax them  
 =/

 But, erm, you don't need alias accepting literals for old syntax!  
 Strings are valid as template value parameters:  
 http://dpaste.1azy.net/54e5d3f2
Hm.. maybe it was a bug that turned into a feature :) Perhaps I'm not remembering correctly why this was introduced. It is true that you could simply accept a literal with an int/long or string, and then you can have different template instantiations based on that. -Steve
May 09 2013