lazy evaluation of logical operators in enum definition

Simen Kjærås simen.kjaras at gmail.com
Tue Apr 17 10:59:44 UTC 2018


On Monday, 16 April 2018 at 05:57:01 UTC, Shachar Shemesh wrote:
> Consider the following program:
>
> struct S1 {
>     enum member = 3;
> }
>
> struct S2 {
>     enum member = 2;
> }
>
> struct S3 {
> }
>
> enum prop(T) = __traits(hasMember, T, "member") && T.member==3;
>
> pragma(msg, prop!S1);
> pragma(msg, prop!S2);
> pragma(msg, prop!S3);
>
> When compiled, it produces:
> true
> false
> test.d(12): Error: no property member for type S3
> test.d(16): Error: template instance `test.prop!(S3)` error 
> instantiating
> test.d(16):        while evaluating pragma(msg, prop!(S3))
>
> If I change the definition of "prop" to:
> template prop(T) {
>     static if( __traits(hasMember, T, "member") && T.member==3 )
>         enum prop = true;
>     else
>         enum prop = false;
> }
>
> then everything compiles as expected.
>
> It seems that the && evaluation does not stop when the first 
> false is found.

There's a kinda neat (and kinda ugly) way to implement prop in 
one line:

     enum prop(T) = __traits(compiles, { static assert(T.member == 
3); });

Now, that's not the same as short-circuiting, and only useful in 
some cases, but for those cases, it's useful.

--
   Simen


More information about the Digitalmars-d mailing list