Thread overview | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
May 09, 2013 Template alias parameter does not accept types | ||||
---|---|---|---|---|
| ||||
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 Re: Template alias parameter does not accept types | ||||
---|---|---|---|---|
| ||||
Posted in reply to ref2401 | 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 Re: Template alias parameter does not accept types | ||||
---|---|---|---|---|
| ||||
Posted in reply to ref2401 | 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 Re: Template alias parameter does not accept types | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | 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 Re: Template alias parameter does not accept types | ||||
---|---|---|---|---|
| ||||
Posted in reply to ref2401 | 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 Re: Template alias parameter does not accept types | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | 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 Re: Template alias parameter does not accept types | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dicebot | 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 Re: Template alias parameter does not accept types | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | 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 Re: Template alias parameter does not accept types | ||||
---|---|---|---|---|
| ||||
Posted in reply to Kenji Hara | 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 Re: Template alias parameter does not accept types | ||||
---|---|---|---|---|
| ||||
Posted in reply to Dicebot | 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
|
Copyright © 1999-2021 by the D Language Foundation