templated overload of opAssign

tsbockman thomas.bockman at gmail.com
Mon Apr 5 20:59:34 UTC 2021


On Monday, 5 April 2021 at 15:05:24 UTC, kdevel wrote:
> You changed the definition of ``bar`` while the exception 
> collector (``EC``) is meant to catch and collect an exception 
> thrown from the *unmodified* function.

My point was that the code will work if you do explicitly what 
`lazy` does implicitly. If you don't want to modify `bar`, then 
it looks like this:

```D
import std.stdio,std.typecons;

struct EC {
     Exception [] ex;
     auto opAssign (X) (scope X f)
         if(is(X : void delegate()) || is(X : void function()))
     {
         writeln (__PRETTY_FUNCTION__);
         try return f (); catch (Exception e) ex ~= e;
     }
}

class E : Exception { this (string s) { super (s); } }
void bar (int i) { if (i == 1) throw new E ("E"); }

void main ()
{
     EC ec;

     ec = () { bar (1); }; // okay

     ec.writeln;
}
```

> It seems that the operator ``+=`` or ``~=`` may be better
> suited to express that intent. Rewriting this in terms of
> ``opOpAssign`` works as expected:

Given that you define the operation to append `~` to `ex` rather 
than overwriting it, `~=` is the best fit, I think.

However, `=` and `~=` should not treat `lazy void` parameters 
differently. They should either both work, or neither. I checked 
and this is actually a very old regression; both worked way back 
in DMD 2.061. So, I've filed a front-end bug report:
     https://issues.dlang.org/show_bug.cgi?id=21802




More information about the Digitalmars-d-learn mailing list