How to avoid variable capturing in `foreach` loop with lambdas?
H. S. Teoh
hsteoh at qfbox.info
Thu Jan 5 23:18:11 UTC 2023
On Thu, Jan 05, 2023 at 10:46:07PM +0000, thebluepandabear via Digitalmars-d-learn wrote:
> On Thursday, 5 January 2023 at 17:36:55 UTC, H. S. Teoh wrote:
[...]
> > ```D
> > foreach (BoardSize boardSize; arr) {
> > Button button = new Button();
> > button.text = format("%sx%s", boardSize[0], boardSize[1]);
> > BoardSize size = boardSize; // force separate capture
> > button.onButtonClick = {
> > eventHandler.settingsWindow_onBoardSizeButtonClick(size);
> > };
> > button.onButtonClick();
> > _boardSizeRow.addChild(button);
> > }
> > ```
[...]
> Your code with the variable capture doesn't seem to work.
Argh, apparently locals inside the loop body are subject to the same
quirky behaviour. >:-( Here's a workaround that works:
foreach (BoardSize boardSize; arr) {
Button button = new Button();
button.text = format("%sx%s", boardSize[0], boardSize[1]);
void wowThisIsDumb(BoardSize size) {
button.onButtonClick = {
eventHandler.settingsWindow_onBoardSizeButtonClick(size);
};
}
wowThisIsDumb(boardSize);
button.onButtonClick();
_boardSizeRow.addChild(button);
}
A nested function (or perhaps an inline lambda) is needed to force the
allocation of a dynamic context for the capture.
This is an embarrassment. Why hasn't this been fixed yet? :-(
T
--
Being able to learn is a great learning; being able to unlearn is a greater learning.
More information about the Digitalmars-d-learn
mailing list