playing around with D

Carsten Scharfenberg cathune_public at web.de
Mon Mar 5 03:17:29 PST 2007


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.



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...



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.



4.

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

Regards,
Carsten Scharfenberg



More information about the Digitalmars-d mailing list