:? in templates

Denis Koroskin 2korden at gmail.com
Wed Nov 18 03:53:50 PST 2009


On Wed, 18 Nov 2009 14:50:42 +0300, Bill Baxter <wbaxter at gmail.com> wrote:

> On Wed, Nov 18, 2009 at 3:36 AM, retard <re at tard.com.invalid> wrote:
>> Wed, 18 Nov 2009 03:31:11 -0800, Bill Baxter wrote:
>>
>>> On Wed, Nov 18, 2009 at 3:16 AM, retard <re at tard.com.invalid> wrote:
>>>> Wed, 18 Nov 2009 03:10:57 -0800, Bill Baxter wrote:
>>>>
>>>>> Didn't this used to work?
>>>>>
>>>>> template factorial(int i) {
>>>>>     enum factorial = (i==0) ? 1 : i*factorial!(i-1);
>>>>> }
>>>>>
>>>>> With DMD 2.036 I'm getting:
>>>>>   Error: template instance factorial!(-495) recursive expansion
>>>>>
>>>>> Seems like it expands both branches regardless of the condition. And
>>>>> seems to me like it shouldn't.
>>>>
>>>> There's probably a confusion here. It evaluates lazily the value of
>>>> factorial!(), but its type (which happens to be infinitely recursive
>>>> must be evaluated eagerly in order to infer the type of the ternary  
>>>> op.
>>>
>>> That makes sense.  I guess the ?: op is defined to do that in all  
>>> cases.
>>>  Might be nice though if it didn't do that in cases where the condition
>>> was statically known.
>>
>> so
>>
>>  int foo = (1==1) ? 6 : "haha";
>>
>> would work, too? I think it would still need to check that the types of
>> both branches match.
>
> Yeh, that could be confusing.
> Actually it would break a lot of code, too, now that I think of it.
> People use typeof(true?a:b) to get the common type.
> That's why it probably needs to be a distinct thing, a static ?:.
>
> --bb

The simplest solution is probably to give the compiler a hint:

enum foo = someStaticCondition ? cast(Foo)SomeTemplate!() :  
cast(Foo)SomeOtherTemplate!();

Looks a bit hackish (and doesn't currently work), though.



More information about the Digitalmars-d mailing list