Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c++

c++11

bind

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?

like image 368
Evelekk Avatar asked Aug 15 '17 17:08

Evelekk


People also ask

Is a general purpose programming language created by Bjarne Stroustrup as an extension of the C programming language or C with classes?

C++ is a general-purpose programming language created by Bjarne Stroustrup as an extension of the C programming language, or “C with Classes”.

What compiler does Bjarne Stroustrup use?

Embarcadero C++ Edison Design Group C++ Front End - used by many C++ compiler suppliers. Green Hills C++ for many embedded systems platforms.

Where does Bjarne Stroustrup teach?

As of July 2022, Stroustrup is a professor of Computer Science at Columbia University.


1 Answers

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

like image 117
Praetorian Avatar answered Oct 07 '22 07:10

Praetorian