The example is incorrect, bind
does make a copy of its arguments unless you wrap it in std::reference_wrapper
as the text correctly says, but that's not what the example shows. In the example, the argument i
is passed to the functor returned by bind
, not to bind
itself. If the example had instead been the following, the value of i
would've remained 2
.
auto inc = bind(incr, i); // a copy of i is made
inc(); // i stays 2; inc(i) incremented a local copy of i
In the example shown in the book, the argument i
will be forwarded to incr
, which will result in an lvalue reference to the original i
being passed to the function, and the original i
will be incremented.
For the relevant standard quotes, from 23.14.11.3
[func.bind.bind]/10
The values of the bound arguments v1
, v2
, …, vN
and their corresponding types V1
, V2
, …, VN
depend on the types TDi
derived from the call to bind
and the cv-qualifiers cv of the call wrapper g
as follows:
...
— if the value j
of is_placeholder_v<TDi>
is not zero, the argument is std::forward<Uj>(uj)
and its type Vi
is Uj&&
;