On Friday, 18 October 2024 at 12:07:24 UTC, Kadir Erdem Demir
wrote:
It seems [=] functionality C++ does not exist in D.
No, D does not have this functionality.
By using a helper function I made that example work.
```d
import std.stdio;
auto localFoo(int x) {
return (){ return x;};
}
void main() {
int x = 10;
auto lambda = (int capturedX = x) {
writeln("Captured reference : ", capturedX);
};
auto localFoo = localFoo(x);
x = 20;
writeln(localFoo());// Outputs: Captured value: 10 --> That
is what I need
lambda(); // Outputs: 20
}
```
D captures all closures via allocation onto the heap. Using
`localFoo` is the correct way to do this.
For nested functions, it has a reference to the outer stack
frame, this is different.
But your example is even different, a default parameter means
"pass this parameter if none is passed". So your call to
`lambda()` is treated as if you wrote `lambda(x)`. It's not
captured on definition, it's passed on usage.
But when I trying the same technique on std.Thread it does not
work. Always reference is being captured.
```d
void InitCurrencies()
{
auto captureFuction(int index)
{
return (){
auto localIndex = index;
string[] currentChunk =
ChunkedExchangePairNames(localIndex);
writeln("Thread index: ", localIndex, " pairs:
", currentChunk.join(";"));
foreach (exchangeName; currentChunk)
Connect(exchangeName, WebSocketType.All);
WebSocket.eventLoop(localLoopExited);
};
}
for(int i = 0; i < m_ThreadCount; i++)
{
auto work = captureFuction(i);
auto worker = new Thread({
work();
});
m_workerList ~= worker;
}
foreach(worker; m_workerList)
{
worker.start();
}
}
```
writeln("Thread index: ", localIndex, " pairs: ",
currentChunk.join(";"))
Always prints the last value of my for loop.
In this case, you are passing in a local anonymous function which
uses the stack frame pointer to find the value stored at `work`.
This value gets changed each time through the loop.
What you need to do is simply pass the work function into the
thread:
```d
auto worker = new Thread(work);
```
This copies the lambda *by value* into the Thread, and then you
can change work, it won't affect that copy.
Note that it is a very long standing issue that closures are not
done based on the full scope of everything -- only the stack
frame of the function is used.
-Steve