Evelekk
Evelekk

Reputation: 169

Mistake with bind in "The C++ Programming Language [4th Edition] - Bjarne Stroustrup"

I found this code in Bjarne Stroustrup's book: Page screenshot

The problem with this code is that variable i does not stay at 2, it is incremented to 3. You can check it here: https://wandbox.org/permlink/p5JC1nOA4pIpsgXb

We do not have to use the std::ref() to increment this variable. Is it a mistake in the book or something has been changed since C++11?

Upvotes: 16

Views: 1487

Answers (1)

Praetorian
Praetorian

Reputation: 109119

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&&;

Upvotes: 11

Related Questions