When foreach-ing over a variadic argument list, lazy arguments are implicitly evaluated, as demonstrated here:
void foo(lazy int n) {}
void bar(T...)(lazy T args) {
foreach (e; args) {
// Look ma, no touchy!
}
}
unittest {
int n = 3;
foo(n++);
assert(n == 3); // passes
bar(n++);
assert(n == 3); // fails
}
Note that static foreach over the same argument list does not evaluate lazy args, and require that arguments be explicitly referenced for evaluation to take place:
auto bar2(T...)(lazy T args) {
static foreach (i, e; args) {
}
}
auto baz2(T...)(lazy T args) {
static foreach (e; args) {
}
}
auto bar3(T...)(lazy T args) {
static foreach (i, e; args) {
e;
}
}
auto baz3(T...)(lazy T args) {
static foreach (e; args) {
e;
}
}
unittest {
int n = 3;
bar2(n++);
assert(n == 3); // passes
baz2(n++);
assert(n == 3); // passes
bar3(n++);
assert(n == 4); // passes
baz3(n++);
assert(n == 5); // passes
}
Comment #1 by robert.schadek — 2024-12-13T18:54:46Z