static try catch construct would be helpful

Bill Baxter dnewsgroup at billbaxter.com
Tue Feb 26 16:39:59 PST 2008


Jason House wrote:
> Bill Baxter wrote:
> 
>> When plugging types together sometimes you find this one is missing a
>> member or that one defines it in a different way than you expect or
>> maybe a function with some signature isn't supported.
>>
>> What you'd like to do is say "compile this block if you can -- otherwise
>> leave it out"  It's like try-catch, but compile-time.
>> Except you don't really want a 'catch'.  It's more like an 'else'.  So I
>> propose a new form of static:
>>
>>     static if {
>>        // some code
>>     } else static if {
>>        // other code
>>     } else {
>>        // last resort code
>>     }
>>
>> The idea is: if "some code" compiles, then use that, otherwise try
>> "other code", and finally if none of the other code blocks compiles, use
>> the else block.
>>
>> And of course it could be mix-n-matched with regular static if()'s.
>>
>>
>> ------
>> Here's a motivating example taken from real code where I was wrapping
>> one struct with another.  The Inner type may or may not support a
>> particular signature of the "doSomething" function.
>>
>> struct Outer(Inner)
>> {
>>     void doSomething(int a, int b, int c, int d)
>>     {
>>        _inner.doSomething(a,b,c,d);
>>        // do something else here
>>     }
>>
>>      ...
>>
>>     Inner _inner;
>> }
>>
>> Currently, the best way I've found to conditionalize that is:
>>
>>     static if(is(typeof(_inner.doSomething(1,1,1,1)))) {
>>     void doSomething(int a, int b, int c, int d)
>>     {
>>        _inner.doSomething(a,b,c,d);
>>        // do something else here
>>     }
>>     }
>>
>> Maybe there's a better way to write that one.. I'm not sure.  But the
>> signature of the thing that may or may not exist can be arbitrarily
>> complex.  It becomes difficult to think of an is-expression that can
>> test for what you want.   You can probably break out the test into a
>> separate template and make it so you can do
>>      static if(is(DoSomeCheck!(....))
>> but writing that DoSomeCheck is annoying too and starts to clutter your
>> source with lots of one-off gobbledy gook templates.
>>
>> I think "argument-less static if blocks" would handle such cases nicely.
>>
>>
>> There's a slight issue in that it could be pretty hard to debug with
>> compiler errors being silently ignored, but that happens currently with
>> the expressions inside "static if(is(...))" already.
>>
>> --bb
> 
> This starts to sound a lot like SFINAE from templates.  Maybe there's a way
> to write it up that way or combine a proposal with how to modify how
> templates are used?  IIRC, there was past discussion about modifications to
> how templates handled errors.

Yeh, I think that was more about forcing a SFINAE error, which would 
still be nice to have.

> 
> I do like the idea of static try{} with else clauses.  Would it be practical
> to make the static try only spill over with static assert failures? (to
> keep error cases under control)

I don't think so.  Having to put the error-causing thing inside an 
assert would mean you have to make it an expression.  If you had such an 
expression for the condition you want to test, then you could just put 
it in a static if -- "static if (is(theExpression))".

So I don't think there'd be much point of having the feature if it only 
worked inside static assert().

--bb



More information about the Digitalmars-d mailing list