Intermediate Gotchas
The Counter That Split in Two
copying the callback quietly forks its history
std::function<int()> make_counter() {
return [count = 0]() mutable { return ++count; };
}
int main() {
auto first = make_counter();
auto second = first;
std::cout << first() << ' ' << second() << '\n';
std::cout << first() << ' ' << second() << '\n';
}
Run it. Does second continue where first left off?
Why¶
std::function has value semantics: copying it copies its stored callable. The mutable
lambda's count is part of that callable object, so the copy starts with the same value but
changes independently afterwards. GCC emits no warning under -Wall -Wextra.
The fix¶
Make the state explicitly shared when copies must observe one counter:
Takeaway: copying a std::function copies the closure and all of its value-captured state.
Try it: g++ -std=c++17 main.cpp -o demo && ./demo