"temporary" templates

Paul Backus snarwin at gmail.com
Wed Nov 27 08:03:58 UTC 2019


On Tuesday, 26 November 2019 at 19:11:14 UTC, Steven 
Schveighoffer wrote:
> On 11/26/19 1:59 PM, Paul Backus wrote:
>> 
>> This will cause compilation to become non-deterministic, since 
>> the result of template evaluation can depend on the order in 
>> which declarations are semantically analyzed:
>> 
>> enum hasFoo(T) = __traits(hasMember, T, "foo");
>> 
>> struct S {
>>      // hasFoo!S is instantiated before the mixin is processed
>>      static if (hasFoo!S) {}
>>      mixin("int foo;");
>> }
>> 
>> pragma(msg, hasFoo!S); // false
>> 
>> If for some reason the "innards" of `hasFoo!S` are discarded 
>> due to memory pressure, reconstructing them later will give a 
>> different result.
>
> But that's an evaluation order issue. hasFoo should be true in 
> both cases. Otherwise, you have the paradox:
>
> static assert(hasFoo!S == __traits(hasMember, T, "foo"))

There are situations where a particular evaluation order is 
forced. For example:

enum hasFoo(T) == __traits(hasMember, T, "foo");

struct S {
     static if (!hasFoo!S) {
         int foo;
     }
}

static assert(hasFoo!S == __traits(hasMember, S, "foo")); // fails

The condition of the static if *must* be evaluated before the 
body, so there is no way to have hasFoo!S evaluate to the same 
thing in both places without causing a paradox. Note that this is 
*not* an accident of the current compiler implementation; it 
follows directly from the definition of `static if` in the 
language spec.


More information about the Digitalmars-d mailing list