What does [] const_iterator :: value_type in std :: transform mean

here is the code specifically. What does line 15 (call for conversion) do?

Can someone explain why this outputs 01234? On the other hand, if I change cb to ++ cb on line 15, it will output 01110. What is the return value on line 15?

#include <algorithm> #include <functional> #include <iostream> #include <iterator> #include <list> int main() { typedef std::list<int> L; L l(5); typedef L::const_iterator CI; CI cb = l.begin(), ce = l.end(); typedef L::iterator I; I b = l.begin(); std::transform(cb, --ce, ++b, [] (CI::value_type n) { return ++n; }); std::copy(l.begin(), l.end(), std::ostream_iterator<CI::value_type>(std::cout)); std::cout << std::endl; return 0; } 
+5
source share
3 answers

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

+2
source

Expression [](CI:value_type n) { return ++n; } [](CI:value_type n) { return ++n; } is a lambda function. Empty brackets mean that it does not have access to the elements of the current area.

transform basically applies this function to each element of the input sequence (l) and writes it to the output sequence (also l). It stops when the item to the last has been reached due to .ce.

The code takes one element from l after another and increments it into the next element l (due to ++ b). Therefore you get 0, 1, 2, 3, 4.

If you change cb to ++ cb, you get 0, 1, 1, 1, 0, because then you start from the element with index 1 and simply increment each to the last.

Find lambda information here.

Std :: transform explanation

+4
source

First, you need to go through the syntax: square brackets mean that your lambda function does not capture anything from the surrounding context. Basically, this is a brief way to connect part of the logic to a call to std::transform : you tell the function that converting a value means adding to it.

To understand what is happening, and also to explain the output of 01110 , let's see what std::transform does: it takes elements from cb (initial element) to --ce (second element from the back) inclusively, calls the lambda function and puts the result, which it returns to cells starting with ++b , i.e. at indices 1, 2, 3, etc.

The first iteration takes zero from L[0] , adds one and writes 1 to L[1] . The second iteration raises 1 from the previous one, adds one and writes 2 to L[2] . The iteration continues until std::transform writes 4 to L[4] .

When replacing cb with ++cb , however, writing is performed in the same cell from which the data was read, i.e. L[1] gets 0+1 , then L[2] gets 0+1 , then L[3] gets 0+1 , and then the loop reaches --ce and stops.

Note that ++n not required, as the side effect of incrementing n disappears as soon as the lambda call is complete. You can replace it with the expression n+1 , which has no side effect:

 std::transform(cb, --ce, ++b, [] (CI::value_type n) { return n+1; }); 
+1
source

Source: https://habr.com/ru/post/1214851/


All Articles