Thread overview | ||||||
---|---|---|---|---|---|---|
|
February 03, 2016 Capturing a variable by value? | ||||
---|---|---|---|---|
| ||||
C++11 allows you to capture a local variable explicitly by value. What is the simplest way to make code below print "0 1 .. 9", like the C++ version does? D version: ``` import std.stdio; void main() { alias F = void delegate(); F[] arr; foreach (i; 0 .. 10) arr ~= { write(i, " "); }; foreach (f; arr) f(); } ``` Prints: 9 9 9 9 9 9 9 9 9 9 C++ version: ``` #include <iostream> #include <functional> #include <vector> using namespace std; int main() { using F = function<void()>; vector<F> arr; for (auto i = 0; i < 10; ++i) arr.push_back([=]() { cout << i << " "; }); for (auto f : arr) f(); } ``` Prints: 0 1 2 3 4 5 6 7 8 9 One stupid solution is to replace `0 .. 10` with staticIota!(0, 10), which would unroll the loop at CT, but I want something more general that would me allow me to capture the values of a range while iterating over it at run-time. |
February 03, 2016 Re: Capturing a variable by value? | ||||
---|---|---|---|---|
| ||||
Posted in reply to ZombineDev | On Wednesday, 3 February 2016 at 18:03:24 UTC, ZombineDev wrote: > C++11 allows you to capture a local variable explicitly by value. > > What is the simplest way to make code below print "0 1 .. 9", like the C++ version does? > > D version: > ``` > import std.stdio; > > void main() > { > alias F = void delegate(); > > F[] arr; > > foreach (i; 0 .. 10) > arr ~= { write(i, " "); }; > > foreach (f; arr) > f(); > } > ``` > Prints: 9 9 9 9 9 9 9 9 9 9 > > > C++ version: > ``` > #include <iostream> > #include <functional> > #include <vector> > using namespace std; > > int main() > { > using F = function<void()>; > > vector<F> arr; > > for (auto i = 0; i < 10; ++i) > arr.push_back([=]() { cout << i << " "; }); > > for (auto f : arr) > f(); > } > ``` > Prints: 0 1 2 3 4 5 6 7 8 9 > > One stupid solution is to replace `0 .. 10` with staticIota!(0, 10), which would unroll the loop at CT, but I want something more general that would me allow me to capture the values of a range while iterating over it at run-time. I think these two links, more or less, answer my question: http://stackoverflow.com/questions/29759419/closures-in-loops-capturing-by-reference https://issues.dlang.org/show_bug.cgi?id=2043 |
February 03, 2016 Re: Capturing a variable by value? | ||||
---|---|---|---|---|
| ||||
Posted in reply to ZombineDev | On Wednesday, 3 February 2016 at 18:09:52 UTC, ZombineDev wrote:
> I think these two links, more or less, answer my question:
> http://stackoverflow.com/questions/29759419/closures-in-loops-capturing-by-reference
> https://issues.dlang.org/show_bug.cgi?id=2043
Another approach:
import std.range, std.array, std.stdio;
struct InputRangeHook(T, alias Fun)
if (isInputRange!T)
{
private T _t;
this(T t)
{
_t = t;
}
void popFront()
{
Fun(front());
_t.popFront;
}
bool empty()
{
return _t.empty();
}
auto front()
{
return _t.front;
}
}
void main()
{
foreach(i; InputRangeHook!(int[],(a) {write(a," ");})(iota(0,10).array)){}
}
|
February 03, 2016 Re: Capturing a variable by value? | ||||
---|---|---|---|---|
| ||||
Posted in reply to ZombineDev | On 02/03/2016 10:09 AM, ZombineDev wrote: > I think these two links, more or less, answer my question: > http://stackoverflow.com/questions/29759419/closures-in-loops-capturing-by-reference > > https://issues.dlang.org/show_bug.cgi?id=2043 I find it more readable to give a name like makeClosure(): foreach (i; 0 .. 10) { auto makeClosure = (int a) { return { write(a, " "); }; }; arr ~= makeClosure(i); } Of course, makeClosure() can be moved out of the loop if needed. Ali |
Copyright © 1999-2021 by the D Language Foundation