playing around with D

Don Clugston dac at nospam.com.au
Mon Mar 5 04:24:18 PST 2007


Carsten Scharfenberg wrote:
> Hello,
> 
> I just downloaded D and now I'm playing around a bit. My oppinion about D is more or the same as every body else's: D is great - but why does this or that feature not work that am I used to from C++... I think that this is just normal for a new langue :-).
> Anyway I have a couple of questions that arose when I had a look into std.bind. I'm using  dmd v1.007 and gdc v0.22 on Linux.
> 
> 
> 1.
> 
> the following behaviour I do not understand:
> 
> 
> struct TupleContainer( T... )
> {
>     alias T tuple;
> 
>     template append( X )
>     {
>         alias TupleContainer!( T, X )   append;
>     }
> }
> 
> template UseAppend( /* alias */ TC )
> {
>     alias TC.append!( int )   UseAppend;
> }
> 
> 
> void main()
> {
>     writefln( typeid( TupleContainer!().append!( int ) ) ); // Ok
>     writefln( typeid( UseAppend!( TupleContainer!() ) ) );  // Error
> }
> 
> 
> 
> Error Message:
> test.d(xxx): Error: template identifier append is not a member of TC
> test.d(xxx): template instance test.UseAppend!(TupleContainer!() ) error
> instantiating
> 
> If I uncomment the alias befor TC everything works fine - why?
> As TC is of type TupleContainer!() which has the member "append" (more precisely: the named template "append" - I'm not sure if this acounts as a member) I would presume this should work without the alias.

I would expect it to work, too. Don't be too surprised if you find 
template bugs -- the D template system is much more extensive than for 
C++, and new features have been added at a terrifying pace.

> 
> 2.
> 
> The second point seems to be a compiler bug - but correct me if I'm wrong:
> 
> 
> 
> template isTupleContainer( T )
> {
>     static if( is( typeof( T.tuple ) ) )
>     {
>         static if( is( T == TupleContainer!( T.tuple ) ) )
>             static const bool isTupleContainer = true;
>         else
>             static const bool isTupleContainer = false;
>     }
>     else
>         static const bool isTupleContainer = false;
> }
> 
> template DoSomething( T )
> {
>     alias T.tuple  OrigTuple;
>     
>     alias int Result;
> }
> 
> template AssertTest( T )
> {
>     static assert( isTupleContainer!( T ) );
>     
>     alias DoSomething!( T ).Result    AssertTest;
> /*      alias int AssertTest;*/
> }
> 
> void main()
> {
>     /*
>      * this is perfectly fine and prints false
>      */
>     writefln( typeid( isTupleContainer!( int ) ) );
>     
>     /*
>      * this should trigger the assert in AssertTest - but it doesn't,
>      * a compiler error is emitted instead.
>      */
>     writefln( typeid( AssertTest!( int ) ) );
> }
> 
> 
> Error Message:
> test.d(xxx): Error: no property 'tuple' for type 'int'
> test.d(xxx): Error: T.tuple is used as a type
> test.d(xxx): template instance test.DoSomething!(int) error instantiating
> 
> 
> isTupleContainer checks, of course, if T is a TupleContainer. This works fine in
> the main function - but in AssertTest its result seems always to be true
> so that the assert is never triggered.
> The assert is triggered in the correct way, if I (1) swap comments for both
> assert lines in AssertTest, or (2) outcomment the first alias line in
> DoSomething! This is very strange...

You're right, something about static assert is a bit weird and doesn't 
work very well. I stopped relying on it, and use a
static if(xxx) { static assert(0, "xxx"); }
combination instead.


> 3.
> 
> Regarding the prevois isTupleContainer template it would be nice to have
> a more general possiblity to check if a type is an arbitary instantiation of a
> given template. It's easy to check for a special instantiation:
> 
> 
> 
> struct Type( T )
> {
>     ...
> }
> 
> template CheckType( T )
> {
>     static if( is( T == Type( int ) ) )
>         static const int CheckType = true;
>     else
>         static const int CheckType = false;
> }
> 
> 
> it is also possible to do the following:
> 
> 
> template isInstantiation( T1, alias T2 )
> {
>     static if( is( T1 t == T2( t ) ) )
>         static const int isInstantiation = true;
>     else
>         static const int isInstantiation = false;
> }
> 
> 
> this checks for an arbitary instantiation of an arbitary template - but only if
> T2 has exactly one template parameter. I'm looking for a possiblity to do this
> check for an arbitary number of template parameters.

I was going to post this as a "Question of the Week" question. It can be 
done with a .mangleof hack, but there ought to be a cleaner way to do it.

> 4.
> 
> By the way: what is the difference between
> static const int        and         const int ?
> Both variants work in the examples above.

I don't know what 'static const int' means. IMHO, it should be a 
compiler error, since you're mixing storage classes (unlike C++, in D, 
'const' really means constant). Use 'const int' instead.



More information about the Digitalmars-d mailing list