www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Why __traits(compile,...) fails here?

reply "Zhenya" <zheny list.ru> writes:
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
}
Aug 07 2012
next sibling parent David <d dav1d.de> writes:
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
Aug 07 2012
prev sibling next sibling parent reply Artur Skawina <art.08.09 gmail.com> writes:
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
Aug 07 2012
parent Timon Gehr <timon.gehr gmx.ch> writes:
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.
Aug 08 2012
prev sibling next sibling parent "Zhenya" <zheny list.ru> writes:
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)
Aug 07 2012
prev sibling next sibling parent Philippe Sigaud <philippe.sigaud gmail.com> writes:
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...)
Aug 07 2012
prev sibling next sibling parent Philippe Sigaud <philippe.sigaud gmail.com> writes:
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).
Aug 08 2012
prev sibling parent "Simen Kjaeraas" <simen.kjaras gmail.com> writes:
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
Aug 08 2012