Intermediate Gotchas
The Callback That Updated a Copy
two increments, and the counter never moves
void increment(int& value) { ++value; }
int main() {
int count = 0;
auto increment_count = std::bind(increment, count);
increment_count();
increment_count();
std::cout << "count: " << count << '\n';
}
Run it. What does the counter print after two increments?
Why¶
std::bind does not preserve a reference merely because the target parameter is int&.
It decay-copies each ordinary bound argument into the callable object, so count becomes
a private stored int. Each call passes that stored value as an lvalue to increment,
letting the private copy reach 2 while the original stays 0. This is valid code, so
-Wall -Wextra emits no warning.
The fix¶
Wrap the argument in std::ref, or use a lambda that captures the original by reference:
auto increment_count = std::bind(increment, std::ref(count));
auto increment_count = [&count] { increment(count); };
Takeaway: std::bind copies bound arguments unless you wrap them in std::ref.
Try it: g++ -std=c++17 main.cpp -o demo && ./demo