playing around with D

Sean Kelly sean at f4.ca
Mon Mar 5 08:16:47 PST 2007


Don Clugston wrote:
> 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.

Doesn't this work?

template isInstantiation( alias T, Args... )
{
     static if( is( T( Args ) ) )
         static const int isInstantiation = true;
     else
         static const int isInstantiation = false;
}

I haven't tried it, but I'd expect it to.


Sean



More information about the Digitalmars-d mailing list