开发者

Question about functors

开发者 https://www.devze.com 2023-02-22 05:39 出处:网络
The correct answer for this is D, but what I\'m confused about is when exactly is the add operation in class dunno taking place? How are the numbers being added?

The correct answer for this is D, but what I'm confused about is when exactly is the add operation in class dunno taking place? How are the numbers being added?

Consider the following partial C++ code:

#include <vector>
#include <iostream>
using namespace std;

template<class Iter, class Formatter>
void mystery(Iter front, Iter end, Formatter doSomething)
{
    while (front != end)
    {
        doSomething(*front, *end):
        front++; end--;
    }
}
template <class T> class dunno
{
public:
    void operator()(T & a, T & b)
    {
        a = a + b;
    }
}
int main()
{
    vector<int> v; ... // insert an odd number of elements into the vector
    vector<int>::iterator it1 - v.begin();
    vector<int>::iterator it2 - v.end();
    it2--;
    dunno<int> d;
    mystery<vector<int>::iterator, dunno<int> >(itl, it2, d);
    for (int i = 0; i < v.size(); i++) cout << v[i] << endl;
    return 0;
}

If you assume that all iterators are bidirectional and non-constant, which of the following statements is true?

(a) This code does not compile because of a type 开发者_如何学编程mismatch in the mystery parameter list.

(b) This code does not compile because of a syntax error in the template instantiation for mystery.

(c) If the vector consists of the integers 1, 2, 3, 4, 5, 6, 7 in that order, with the first item on the left, then the output is 1, 2, 3, 4, 5, 6, 7. (i.e. the code dods not change the vector.)

(d) If the vector consists of the integers 1, 2, 3, 4, 5, 6, 7 in that order, with the first item on the left, then the output is 8, 8, 8, 4, 5, 6, 7.

(e) None of these options describes the behavior of this code.


When we call mystery()

   | 1 | 2 | 3 | 4 | 5 | 6 | 7 |

     ^                       ^
     |                       |
   front                    end


front   is from v.begin();
end     is from v.end() (note: this is one past the end)
        followed by a -- operator that moves it back one.

Now we start the loop:

while(front != end)

So this will loop while they are not equal. and inside the loop both are moved at the same time:

front++; end--;

So each iteration will look like this:

Iteration 1:
   | 1 | 2 | 3 | 4 | 5 | 6 | 7 |

     ^                       ^
     |                       |
   front                    end

Iteration 2:
   | 1 | 2 | 3 | 4 | 5 | 6 | 7 |

         ^               ^
         |               |
       front            end

Iteration 3:
   | 1 | 2 | 3 | 4 | 5 | 6 | 7 |

             ^       ^
             |       |
           front    end

The loop is not entered.
   | 1 | 2 | 3 | 4 | 5 | 6 | 7 |

                 ^
                 |
           front   end

So each time through the loop we also do:

doSomething(*front, *end):

Now doSomething is an object of type Formatter (template parameter) which decodes to the type dunno<int> which has the method void operator()(T & a, T & b) which after replacing the template parameters T we get void operator()(int & a, int & b).

So the line:

doSomething(*front, *end):

is syntactic sugar for:

doSomething.operator()(*front, *end):

Which has the effect of calling this operator passing the de-referenced iterators as argument. This is effectively the same as:

Iteration 1:
    v[0]    = v[0] + v[6]; // Note v[0] == 1 v[6] == 7 etc.
  //v[0]    =  1   +   7;

Iteration 2:
    v[1]    = v[1] + v[5];
  //v[1]    =  2   +   6

Iteration 3:
    v[2]    = v[2] + v[4];
  //v[2]    =  3   +   5

Thus if your start array is:

1 2 3 4 5 6 7

The end result is:

8 8 8 4 5 6 7


the dunno functor's operator() is being called inside mystery for every call to doSomething. Since the arguments are passed by reference the value passed in as 'a' will be updated each time. so what you end up with is a list that has 1+7, 2+6, 3+5, 4, 5, 6, 7. Because when the iterators meet at the value 4 the loop inside mystery ends.


The dunno instance d is passed as an argument to mystery, then designated by the formal parameter doSomething and its operator() is called inside the while loop.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号