digitalmars.D.learn - An issue with lazy delegates
- Andrej Mitrovic (47/47) Jan 04 2012 import std.stdio;
- Peter Alexander (13/17) Jan 06 2012 void test(T)(lazy T dg)
- Andrej Mitrovic (1/1) Jan 06 2012 Hah, I never thought of using that check. Thanks.
-
Stewart Gordon
(10/14)
Jan 09 2012
import std.stdio; void test(T)(lazy T dg) { test2(dg); } void test2(T)(lazy T dg) { dg(); // nothing happens dg()(); // have to use double-invocation instead } void main() { test({ writeln("test"); }); } Do you think it would be possible for the compiler to avoid wrapping delegates into another delegate? I'm having this problem with this sort of template: import std.conv; import std.string; auto onFailThrow(E, T)(lazy T dg) { try { static if (is(ReturnType!T == void)) dg(); else return dg(); } catch (Exception ex) { throw new E(ex.msg); } } void main() { string x = "x"; string y = "y"; onFailThrow!Exception({ to!int(x); }); onFailThrow!Exception(to!int(y)); } The first call doesn't do anything because the delegate is wrapped inside of another delegate. I want this template to be versatile enough to be used by both lazy expressions and delegate literals, but I don't know how. If I write the same template but with "lazy" stripped off I'll have conflicting templates, but I don't know how I would write constraints to separate the two. Any ideas?
Jan 04 2012
On 5/01/12 5:26 AM, Andrej Mitrovic wrote:The first call doesn't do anything because the delegate is wrapped inside of another delegate. I want this template to be versatile enough to be used by both lazy expressions and delegate literals, but I don't know how.void test(T)(lazy T dg) { static if (is(T == delegate)) dg()(); else dg(); } void main() { test( writeln("a") ); test( { writeln("b"); } ); }
Jan 06 2012
Hah, I never thought of using that check. Thanks.
Jan 06 2012
On 05/01/2012 05:26, Andrej Mitrovic wrote: <snip>The first call doesn't do anything because the delegate is wrapped inside of another delegate. I want this template to be versatile enough to be used by both lazy expressions and delegate literals, but I don't know how.<snip> If you have a delegate you want to use as a lazy expression, you can make the lazy argument a call to it onFailThrow!Exception({ to!int(x); }()); Of course, Peter's solution enables you to omit the () and just pass the delegate in, but it does mean that you can't lazily evaluate an expression to a delegate, unless you wrap it in a delegate literal. Stewart.
Jan 09 2012