Thread overview
Why __traits(compile,...) fails here?
Aug 07, 2012
Zhenya
Aug 07, 2012
David
Aug 07, 2012
Artur Skawina
Aug 07, 2012
Zhenya
Aug 07, 2012
Philippe Sigaud
Aug 08, 2012
Timon Gehr
Aug 08, 2012
Philippe Sigaud
Aug 08, 2012
Simen Kjaeraas
August 07, 2012
import std.stdio;

template isType(alias s)
{
	enum isType = !__traits(compiles,mixin("typeof(s)"));
}

void main()
{
//	writeln(isType!int);// Error: template instance isType!(int) isType!(int) does not match template declaration isType(alias s)
	writeln(__traits(compiles,mixin("typeof(int)")));//write: false
}
August 07, 2012
Am 07.08.2012 09:51, schrieb Zhenya:
> import std.stdio;
>
> template isType(alias s)
> {
>      enum isType = !__traits(compiles,mixin("typeof(s)"));
> }
>
> void main()
> {
> //    writeln(isType!int);// Error: template instance isType!(int)
> isType!(int) does not match template declaration isType(alias s)
>      writeln(__traits(compiles,mixin("typeof(int)")));//write: false
> }

http://dpaste.dzfl.pl/bd54413f
August 07, 2012
On 08/07/12 09:51, Zhenya wrote:
> import std.stdio;
> 
> template isType(alias s)
> {
>     enum isType = !__traits(compiles,mixin("typeof(s)"));
> }
> 
> void main()
> {
> //    writeln(isType!int);// Error: template instance isType!(int) isType!(int) does not match template declaration isType(alias s)
>     writeln(__traits(compiles,mixin("typeof(int)")));//write: false
> }

Template alias parameters do not accept built-in types.

   template isType(s) /*...*/

would compile.

artur
August 07, 2012
On Tuesday, 7 August 2012 at 09:47:58 UTC, Artur Skawina wrote:
> On 08/07/12 09:51, Zhenya wrote:
>> import std.stdio;
>> 
>> template isType(alias s)
>> {
>>     enum isType = !__traits(compiles,mixin("typeof(s)"));
>> }
>> 
>> void main()
>> {
>> //    writeln(isType!int);// Error: template instance isType!(int) isType!(int) does not match template declaration isType(alias s)
>>     writeln(__traits(compiles,mixin("typeof(int)")));//write: false
>> }
>
> Template alias parameters do not accept built-in types.
> 
>    template isType(s) /*...*/
>
> would compile.
>
> artur

Thank you)


August 07, 2012
On Tue, Aug 7, 2012 at 12:42 PM, Zhenya <zheny@list.ru> wrote:

>> Template alias parameters do not accept built-in types.

The trick is:

- A template type parameter (like (T)) recognizes types
- A template alias parameter(like (alias a)) recognizes names, symbols.

A built-in type is 'purely' a type. It's a keyword, and hence it's not
a symbol ('int' cannot be a D identifier)
A user-defined type is *both* a type and a symbol (because it has a name)

So, given:

class C {}
template isType(T) { ... }
template isName(alias name) { ... }

then

isType!int => accepted
isType!C => accepted

isName!int => not accepted
isName!C => accepted

which also means you can design a template that accepts

- only built-in types
- only user-defined types
- both
- neither (with other template parameters...)
August 08, 2012
On 08/07/2012 03:52 PM, Philippe Sigaud wrote:
> On Tue, Aug 7, 2012 at 12:42 PM, Zhenya<zheny@list.ru>  wrote:
>
>>> Template alias parameters do not accept built-in types.
>
> The trick is:
>
> - A template type parameter (like (T)) recognizes types
> - A template alias parameter(like (alias a)) recognizes names, symbols.
>
> A built-in type is 'purely' a type. It's a keyword, and hence it's not
> a symbol ('int' cannot be a D identifier)
> A user-defined type is *both* a type and a symbol (because it has a name)
> ...

Yes, but note that this distinction does not make any sense.

alias int Int; // works

isType!Int // 'Int' is clearly a symbol, yet the instantiation fails.

alias declarations should just accept built-in types. If someone for
some obscure reason needs to exclude them, template constraints are
good enough. There is no reason to make built-in types behave specially
here.

August 08, 2012
On Wed, Aug 8, 2012 at 11:13 AM, Timon Gehr <timon.gehr@gmx.ch> wrote:

> Yes, but note that this distinction does not make any sense.
>
> alias int Int; // works
>
> isType!Int // 'Int' is clearly a symbol, yet the instantiation fails.
>
> alias declarations should just accept built-in types. If someone for some obscure reason needs to exclude them, template constraints are good enough. There is no reason to make built-in types behave specially here.

Yes, alias has different semantics depending on its use (in template
param list or as a statement).
August 08, 2012
On Wed, 08 Aug 2012 11:13:30 +0200, Timon Gehr <timon.gehr@gmx.ch> wrote:

> Yes, but note that this distinction does not make any sense.
>
> alias int Int; // works
>
> isType!Int // 'Int' is clearly a symbol, yet the instantiation fails.

I'm not sure it is 'clearly' a symbol. To the compiler, there is no
difference between int and your Int - they're just different names for
the exact same thing. Depending on when the translation occurs, it may
not be sensible to think of them as separate.


> alias declarations should just accept built-in types. If someone for
> some obscure reason needs to exclude them, template constraints are
> good enough. There is no reason to make built-in types behave specially
> here.

Agreed.

-- 
Simen