In this statement
L l(5);
a list of 5 elements is created, each of which is initialized to 0.
In this call
std::transform(cb, --ce, ++b, [] (CI::value_type n) { return ++n; });
cb points to the first element of the list. --ce after evaluation, the decrement operator points to the last element of the list. So cb and --ce specify a range of list items
[cb, --ce)
where brackets mean --ce not in the range.
++b after evaluating the increment points to the second element of the list. So you have
b | 0 0 0 0 0 ^ ^ | | cb ce
The value indicated by cb, which is the value of the first element of the list, is incremented in the lambda expression
[] (CI::value_type n) { return ++n; }
and is written in the second element of the list pointed to by the iterator b. Thereafter
and
b increase in the body of the transform.
So, after the first iteration, the list looks like
b | 0 1 0 0 0 ^ ^ | | cb ce
Now cb points to the second element of the list. Its value is incremented in the lambda expression and is written in the third element pointed to by the iterator b .
b | 0 1 2 0 0 ^ ^ | | cb ce
As a result, you will get the list that will have the values 0, 1, 2, 3, 4.
If you write an algorithm call like
std::transform(++cb, --ce, ++b, [] (CI::value_type n) { return ++n; });
which uses ++cb and then cb and b will point to the same element, and the algorithm will simply rewrite each element with its added value, starting from the second element of the list, because the ++cb iterator was used. The result will be 0, 1, 1, 1, 0