| Thread overview | ||||||
|---|---|---|---|---|---|---|
|
January 05, 2012 An issue with lazy delegates | ||||
|---|---|---|---|---|
| ||||
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?
| ||||
January 07, 2012 Re: An issue with lazy delegates | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Andrej Mitrovic | 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"); } );
}
| |||
January 07, 2012 Re: An issue with lazy delegates | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Peter Alexander | Hah, I never thought of using that check. Thanks. | |||
January 09, 2012 Re: An issue with lazy delegates | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Andrej Mitrovic | 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.
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply