digitalmars.D.learn - Capturing a variable by value?
- ZombineDev (41/41) Feb 03 2016 C++11 allows you to capture a local variable explicitly by value.
- ZombineDev (4/46) Feb 03 2016 I think these two links, more or less, answer my question:
- Basile B. (30/33) Feb 03 2016 Another approach:
- =?UTF-8?Q?Ali_=c3=87ehreli?= (11/14) Feb 03 2016 I find it more readable to give a name like makeClosure():
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.
 Feb 03 2016
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
 Feb 03 2016
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=2043Another 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)){} }
 Feb 03 2016
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-ca turing-by-referencehttps://issues.dlang.org/show_bug.cgi?id=2043I 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
 Feb 03 2016








 
  
  
 
 Basile B. <b2.temp gmx.com>
 Basile B. <b2.temp gmx.com> 